1. jmap: magie en ligne de commande
Le ramasse-miettes automatique, c’est évidemment formidable. Mais même les applications Java peuvent « fuir » (OutOfMemoryError), être lentes ou subir des à-coups à cause d’un mauvais usage de la mémoire. Les causes peuvent être diverses:
- Fuites mémoire (memory leaks): des objets qui auraient dû être collectés continuent de « vivre ».
- Des volumes de données trop importants dans les collections.
- Des erreurs dans la logique de mise en cache.
- Des ressources non libérées (par exemple, threads, fichiers).
Votre objectif — apprendre à localiser rapidement ce type de problèmes. Sinon, vous risquez de devenir non pas développeur, mais « développeur de bugs »!
Qu’est-ce que jmap?
jmap est un utilitaire inclus dans le JDK standard. Il permet d’obtenir un « instantané » (heap dump) de la mémoire d’un processus Java en cours d’exécution. Cet instantané peut ensuite être ouvert dans d’autres outils pour voir quels objets occupent la mémoire, combien ils sont et qui y fait référence.
Heap dump — c’est comme une photo de votre tas: tous les objets qu’il contient, leurs types, liens et tailles.
Comment utiliser jmap
Trouvez le PID du processus
Pour commencer, il faut connaître l’identifiant du processus (PID) dans lequel tourne votre application Java. Plusieurs méthodes existent:
Avec jps (un autre utilitaire du JDK):
jps -l
Vous verrez la liste des processus Java et leurs PID.
Via le gestionnaire des tâches (Task Manager) ou ps sous Linux.
Générez un dump mémoire
jmap -dump:format=b,file=heap.bin <PID>
- format=b — format binaire (adapté à l’analyse).
- file=heap.bin — nom du fichier où le dump sera enregistré.
- <PID> — identifiant du processus.
Exemple:
jmap -dump:format=b,file=heap.bin 12345
Que faire du heap dump?
En général, on analyse le dump avec des outils graphiques (par exemple, jvisualvm ou Eclipse MAT), car chercher des objets à la main dans un fichier binaire — c’est du grand art et un brin masochiste.
Autres possibilités de jmap
Afficher les statistiques mémoire:
jmap -heap <PID>
Affiche des informations sur le tas: taille, GC utilisé, état.
Liste des classes:
jmap -histo <PID>
Affiche des statistiques par classe: combien d’objets de chaque type, taille totale.
Exemple de sortie:
| # | Objet | Nombre | Octets |
|---|---|---|---|
| 1 | |
1200 | 48000 |
| 2 | |
1000 | 32000 |
| 3 | |
200 | 12800 |
Cela donne déjà une idée: si vous avez soudain des millions d’objets d’un certain type — il y a matière à réflexion.
2. jvisualvm: analyseur mémoire visuel
jvisualvm est un programme graphique inclus dans le JDK (voir le dossier bin). Il permet de se connecter à des processus Java locaux (et parfois distants), de les monitorer en temps réel, de prendre un heap dump, de consulter les statistiques de mémoire, threads, GC, CPU et même de profiler l’exécution du code.
Si vous aimez cliquer à la souris et regarder de jolis graphiques — c’est l’outil qu’il vous faut.
Comment lancer jvisualvm
En ligne de commande (ou via un raccourci sous Windows):
jvisualvm
Une fenêtre s’ouvre avec la liste de tous les processus Java locaux.
Fonctions principales de jvisualvm
Surveillance mémoire en temps réel
- Sélectionnez le processus dans la liste de gauche.
- Allez dans l’onglet Monitor.
- Vous verrez des graphiques d’utilisation du heap, du CPU, le nombre de threads et de classes.
Exemple:

Heap Dump (instantané mémoire)
- Dans le panneau Monitor, cliquez sur Heap Dump.
- Au bout de quelques secondes, un onglet d’analyse du dump apparaît.
- Vous verrez la liste de toutes les classes, le nombre d’objets, leur taille totale.
Recherche d’objets « lourds »
- Triez par taille ou par quantité.
- Si vous voyez qu’un type (par exemple, ArrayList ou String) occupe trop de mémoire — c’est un motif d’enquête.
Analyse des références (Reference Graph)
- Cliquez sur une classe — vous verrez qui référence les objets de cette classe.
- On peut remonter jusqu’à la racine: pourquoi l’objet n’est pas collecté par le GC.
Analyse des threads
- L’onglet Threads affiche tous les threads et leur état.
- Vous pouvez repérer des threads « bloqués » ou trop actifs.
Profilage
- L’onglet Profiler permet de mesurer quelles méthodes consomment le plus de temps ou de mémoire.
- C’est une analyse plus poussée, mais pour traquer les fuites mémoire, les premières étapes suffisent.
3. Pratique: analyser une fuite mémoire
Exemple de code avec fuite
import java.util.ArrayList;
import java.util.List;
public class MemoryLeakDemo {
// Collection statique — un grand classique !
private static final List<String> bigList = new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 1_000_000; i++) {
bigList.add("Ligne numéro " + i);
if (i % 100_000 == 0) {
System.out.println("Ajouté : " + i);
Thread.sleep(500); // On laisse du temps pour l’analyse
}
}
System.out.println("Terminé ! Ne fermez pas l’application, ouvrez jvisualvm.");
Thread.sleep(600_000); // 10 minutes — temps pour l’analyse
}
}
Que se passe-t-il?
- Nous créons une liste statique et y ajoutons un million de chaînes.
- Après l’ajout, le programme « se met en pause » pour que vous puissiez vous y connecter avec des outils d’analyse.
Analyse avec jvisualvm
- Lancez le programme.
- Ouvrez jvisualvm et sélectionnez le processus.
- Dans l’onglet Monitor, regardez le graphique mémoire.
- Si tout va bien, la mémoire devrait se libérer après les GC.
- En cas de fuite, la mémoire ne fait que croître.
- Faites un Heap Dump.
- Regardez quels objets occupent le plus de mémoire.
- Dans notre cas — java.util.ArrayList et java.lang.String.
- Cliquez sur l’objet — voyez qui y fait référence.
- Vous verrez qu’il s’agit du champ statique bigList.
Comment corriger?
- Supprimez les éléments inutiles des collections et limitez leur croissance.
- Mettez à null les références vers les objets lourds lorsqu’ils ne sont plus nécessaires.
- N’entreposez pas de grandes collections en static si elles ne sont pas nécessaires en permanence.
4. Autres outils: Eclipse MAT, jconsole
Eclipse Memory Analyzer (MAT)
Eclipse MAT est un outil gratuit mais puissant pour analyser les heap dump. Il permet de voir quels objets occupent la mémoire et lesquels en retiennent d’autres — le retained set. Cela permet d’identifier précisément où se cache la fuite.
L’outil sait générer des rapports détaillés sur les objets suspects (leak suspects) et gère sans broncher des dumps gigantesques de plusieurs gigaoctets.
Le fonctionnement est simple: vous capturez un dump mémoire avec jmap ou jvisualvm, vous l’ouvrez dans MAT, vous cliquez sur le bouton Leak Suspects Report — et vous obtenez un rapport prêt à l’emploi avec les problèmes potentiels déjà mis en évidence.
jconsole
jconsole est un outil simple et pratique pour observer la JVM en temps réel. Il indique la mémoire utilisée, la charge CPU, le nombre de threads actifs et le comportement du GC.
Contrairement à des outils plus avancés comme VisualVM, jconsole n’analyse pas les heap dump, mais il est parfait pour un diagnostic rapide — quand il faut d’un coup d’œil comprendre ce qui se passe dans l’application.
5. Erreurs typiques lors de l’analyse mémoire
Erreur n°1: vous faites un dump du mauvais processus. Souvent, plusieurs applications Java tournent sur la machine, et l’on peut confondre PID. Vérifiez via jps et assurez‑vous d’analyser votre application.
Erreur n°2: vous attendez de voir une « fuite » là où il n’y en a pas. Le GC peut ne pas supprimer les objets immédiatement — parfois la mémoire ne se libère qu’après un Full GC. Ne paniquez pas si après une itération la mémoire ne s’est pas libérée — regardez la tendance.
Erreur n°3: vous n’intégrez pas l’impact des objets statiques/en cache. Beaucoup de fuites sont dues au fait que des objets sont conservés dans des champs static ou des collections globales. Vérifiez qui référence les objets « lourds » — c’est souvent du static.
Erreur n°4: ne pas profiler en dynamique. Heap dump — c’est bien, mais il est parfois important d’observer l’évolution de la mémoire dans le temps (graphiques dans jvisualvm). Si la mémoire augmente de façon continue — il y a matière à enquête.
Erreur n°5: vous n’enlevez pas les listeners/gestionnaires d’événements. Si vous vous êtes inscrit à un événement mais ne vous êtes pas désinscrit — l’objet « vivra » en mémoire, même si vous ne l’utilisez plus.
Conseil: N’ayez pas peur d’expérimenter avec les outils! Faites des dumps, regardez les graphiques, cliquez sur les objets — c’est ainsi que vous apprendrez à « sentir » la mémoire de votre programme et à trouver rapidement les problèmes.
GO TO FULL VERSION