Vous avez diagnostiqué une fuite mémoire et vous voulez corriger le problème.
Si vous utilisez IntelliJ, vous avez à disposition dans votre IDE un outil puissant qui vous permettra de diagnostiquer la source du problème et vérifier votre correction : le profiler.
On va voir à travers un exemple concret comment il peut nous aider.
La fuite mémoire
Je crée une fuite mémoire avec BouncyCastle:
Cipher.getInstance("AES/ECB/PKCS5Padding", new BouncyCastleProvider());
Ici, à chaque appel de mes méthodes “encrypt” et “decrypt”, on ajoute une instance de BouncyCastleProvider qui ne sera jamais clean.
Au bout d’un moment, notre Heap sera pleine et notre serveur va exploser 💥
Trouver le coupable
Dans l’onglet “profiler” vous pouvez ouvrir un fichier hprof ou jfr afin d’analyser leur résultat :
Via un flame graph, on isole le responsable
Pour s’en convaincre appelons cette méthode en boucle dans un test unitaire et affichons la consommation mémoire:
@Test
void shouldNotOverflow() throws Exception {
String password = "M0nSup3rP4ssw0rd";
byte[] encryptedPassword;
String decryptedPassword = "";
// Le temps d'ouvrir le profiler
Thread.sleep(5000);
SecretKey secretKey = getSecretKey();
for (int i = 0; i < 2000; i++) {
encryptedPassword = encrypt(password.getBytes(StandardCharsets.UTF_8), secretKey);
decryptedPassword = decrypt(encryptedPassword, secretKey);
}
assertThat(decryptedPassword).isEqualTo(password);
}
Faites un clic droit sur le process Junit puis sélectionnez “CPU and Memory Live Charts”
Vous allez voir la Heap monter progressivement jusqu’à saturation:
Vous pouvez aussi cliquer sur l’option “profile” afin d’analyser le processus de test
L’analyse commence:
Ouvrez le rapport généré et sélectionnez « Memory Allocations » en haut à droite.
Sélectionnez l’onglet “Call Tree” à gauche. On voit que le test a eu une allocation de plus de 10 Go !
Astuce
Vous pouvez enlever le “thread sleep” du test en désactivant le changement d’onglet au lancement du test
Editez votre configuration:
En bas, cliquez sur la croix à droite de “Open run/debug tool window when started” puis “ok”.
Vous pouvez retirer la boucle dans le test et répéter le test jusqu’à ce qu’il soit stoppé manuellement:
Cliquez ensuite sur “Modify options”
Corriger le problème
Une fois qu’on a trouvé le coupable, on va pouvoir investiguer et trouver une solution au problème.
Dans mon cas, ça sera simplement de faire:
Cipher.getInstance("AES/ECB/PKCS5Padding");
Afin d’utiliser toujours le même provider.
Avec les outils qu’on a vu précédemment, il sera très facile de voir si on a résolu le problème sans tester en production.
Dans le profiler, je sélectionne à nouveau “CPU and Memory Live Charts” sur le process Junit:
On a quelques dizaines de Mo de conso mémoire, c’est bien mieux !
Visuellement, on voit bien que la Heap ne monte pas aussi haut qu’avant 😌
Conclusion
J’espère que cet article vous aura permis d’en apprendre un peu plus sur le profiler IntelliJ. Si jamais vous connaissez d’autres fonctionnalités utiles, n’hésitez pas à les mettre en commentaire 🙂
Il arrive que la code review nous empêche de merge nos PR assez vite et qu’on se retrouve à tirer une branche d’une branche de travail pour avancer 😔
Une fois la première PR squash et merge, la PR issue de la seconde branche se retrouve avec des conflits 💥
Si vous avez déjà vécu cette situation, il y a de bonnes chances que vous ayez cherry-pick vos commits de travail sur une...
Il arrive souvent que pour tester unitairement des règles de validation, on doive tester le même cas mais avec des exemples différents. Sans tests paramétrés, ça revient à faire un test par cas ce qui peut alourdir notre fichier de tests.
On va voir comme...
Avant .Net 8, tester du code qui utilise DateTime.Now() n’était pas trivial, on devait faire en sorte de mocker la Clock dans nos tests. Depuis .Net 8, c’est beaucoup plus facile grâce à TimeProvider inclut par défaut !
En deux mots, TimeProvider est une...
La gestion des erreurs de son API est très importante pour que les consommateurs puissent avoir une description claire du problème mais c’est souvent fastidieux à maintenir.
On va voir comment avoir des statuts de réponse cohérent et des messages d’erre...