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 🙂
Introduction
Sur un des projets sur lesquels j’interviens, diverses personnes ont contribué au cours des années parfois sans passation entre les équipes.
En regardant les commits, on voit qu’une équipe a mis un ORM, une autre l’a enlevé, une autre a mis un autre ORM etc..
Le coût en temps pour l’entreprise est considérable car ce n’est pas une opération a...
Introduction
JaCoCo est un outil très connu dans le monde Java qui permet de générer des rapports de code coverage au format xml et html.
L’intérêt sera souvent de donner le rapport au format xml à d’autres outils (Codecov ou Sonar par exemp...
Introduction
Dans nos applications, il y a souvent des objets qui dépendent les uns des autres (un Service avec des Repository par exemple). Si on devait satisfaire ces dépendances “à la main”, on devrait les instancier, vérifier que ça n’ait pas ...
Introduction
Chiffrer et déchiffrer des informations est un besoin qu’on rencontre souvent dans nos projets et Java donne nativement une palette d’outils pour y arriver. On va voir dans cet article comment réaliser ces deux opérations via un cas prati...