1. JMX (Java Management Extensions) : le cœur de la surveillance de la JVM
La surveillance, c’est comme un bilan de santé régulier pour votre application. Si la journalisation peut être comparée à un journal où l’on écrit tout ce qui s’est déjà produit, la surveillance est un ensemble d’instruments qui indiquent l’état du système à l’instant T : température, pouls, pression, glycémie et autres indicateurs vitaux de la JVM.
Elle aide à comprendre combien de mémoire est réellement utilisée et si elle ne fuit pas, combien de threads fonctionnent et dans quel état ils se trouvent — en attente, en cours d’exécution ou bloqués. Vous pouvez voir à quelle fréquence le ramasse-miettes se déclenche, le niveau de charge du processeur et repérer à temps des signaux d’alerte comme une hausse soudaine de la mémoire ou du nombre de threads.
En bref, la journalisation raconte ce qui s’est déjà passé, tandis que la surveillance montre ce qui se passe en ce moment.
Bases de JMX : qu’est-ce que c’est et à quoi ça sert
JMX est une technologie Java qui permet d’observer la vie de votre application de l’intérieur et même de la piloter un peu. Elle fonctionne via des objets spéciaux — les MBean (Management Bean). On peut dire que ce sont des « capteurs » et des « interrupteurs » à l’intérieur de la JVM : certains affichent l’état du système, d’autres permettent d’ajuster des paramètres.
Avec JMX, vous pouvez savoir combien de mémoire est actuellement allouée à la JVM, combien de threads sont actifs, combien de temps prend la collecte des déchets, et bien plus — sans avoir à toucher au code ni à redémarrer l’application.
Comment ça marche
Dans la JVM, de nombreux MBeans sont déjà disponibles « prêts à l’emploi » et fournissent des informations sur :
- la mémoire (heap, non-heap) ;
- les ramasse-miettes (GC) ;
- les threads ;
- les classes (combien sont chargées, déchargées) ;
- et même sur la JVM elle-même (version, paramètres de lancement).
JMX, c’est comme un tableau de bord automobile. Vous voyez la vitesse, le régime, la température moteur — et tout cela est accessible via des capteurs standard (MBeans).
Comment accéder à JMX
La façon la plus simple est d’utiliser l’outil standard JConsole, fourni avec le JDK.
Démarrer JConsole
- Ouvrez un terminal/une invite de commande.
- Exécutez la commande :
jconsole - Sélectionnez le processus Java que vous souhaitez surveiller (par exemple, votre application).
JConsole se connecte à la JVM via JMX et affiche des graphiques et des tableaux : utilisation de la mémoire, nombre de threads, activité du ramasse-miettes, etc.
Exemple : consulter la mémoire et les threads
Dans JConsole, ouvrez les onglets "Memory" et "Threads". Vous verrez comment évolue la quantité de mémoire utilisée, combien de threads sont vivants, lesquels sont actifs et lesquels sont en attente.
MBeans personnalisés
Vous pouvez créer vos propres MBeans pour surveiller des métriques spécifiques (par exemple, le nombre de commandes traitées). Mais c’est déjà un sujet avancé : les MBeans standard fournissent énormément d’informations.
2. VisualVM — surveillance visuelle et profilage
Si JConsole est un « tableau de bord », alors VisualVM est un centre de diagnostic complet avec radiographie, IRM et analyses. Il permet non seulement de surveiller, mais aussi de profiler l’application, de réaliser un heap dump, d’analyser les fuites et de voir quelles méthodes consomment le plus de temps.
Installation et lancement de VisualVM
- VisualVM est fourni avec le JDK (généralement sous le nom jvisualvm), mais vous pouvez télécharger la version la plus récente sur visualvm.github.io.
- Se lance avec la commande :
jvisualvm - Après le démarrage, vous verrez la liste de tous les processus Java en cours d’exécution sur votre machine.
Connexion à un processus
- Trouvez votre processus (par exemple, Main ou MyApp) dans la liste.
- Double-cliquez dessus — un onglet d’informations sur le processus s’ouvrira.
- C’est fait ! Vous voyez maintenant :
- L’utilisation du CPU et de la mémoire en temps réel.
- Le nombre de threads et leur état.
- La liste des classes chargées.
- La possibilité d’effectuer un heap dump et un thread dump.
Fonctionnalités principales de VisualVM
Avec VisualVM, vous pouvez observer l’utilisation de la mémoire — à la fois le heap et le non-heap. Le graphique montre si la consommation augmente ou se stabilise. Pour vérifier le fonctionnement du ramasse-miettes, cliquez sur le bouton "Perform GC" — la JVM tentera immédiatement de nettoyer la mémoire. Vous pouvez faire un heap dump (instantané de la mémoire) et l’étudier pour rechercher des fuites.
L’outil affiche aussi l’état des threads : combien sont lancés, lesquels travaillent, attendent ou sont bloqués. En cas de deadlock, VisualVM aide à le détecter et à montrer les interblocages.
Pour une analyse approfondie, il y a le profilage : vous verrez les méthodes « chaudes » qui consomment le plus de temps processeur ou de mémoire. C’est utile pour diagnostiquer une chute inattendue des performances.
Exemple : surveiller une mini‑application
public class MemoryLeakDemo {
public static void main(String[] args) throws InterruptedException {
List<byte[]> memoryConsumers = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
memoryConsumers.add(new byte[1024 * 1024]); // 1 Mo
Thread.sleep(100); // On patiente un peu pour rendre le graphique plus lisse
}
System.out.println("Terminé ! N’oubliez pas de regarder dans VisualVM :)");
Thread.sleep(60000); // Laisser l’application ouverte pour l’analyse
}
}
Maintenant :
- Lancez le programme.
- Ouvrez VisualVM, connectez-vous au processus.
- Observez l’augmentation de l’utilisation de la mémoire.
- Effectuez un heap dump, trouvez les tableaux qui occupent la mémoire.
3. Java Flight Recorder (JFR) : la boîte noire de la JVM
Qu’est-ce que JFR
Java Flight Recorder est un outil intégré à la JVM pour collecter des événements détaillés sur le fonctionnement de l’application. C’est une « boîte noire » : JFR écrit ce qui se passe dans la JVM, afin de retrouver ensuite les goulots d’étranglement ou les causes d’un incident.
JFR collecte :
- des événements GC ;
- des informations sur les threads ;
- la fréquence des appels de méthodes et des profils de temps ;
- des pauses et des latences ;
- des exceptions et des erreurs.
Comment activer JFR
Depuis Java 11+, JFR est directement inclus dans OpenJDK.
Démarrer avec JFR
java -XX:StartFlightRecording=filename=recording.jfr,duration=60s,settings=profile -jar MyApp.jar
- filename=recording.jfr — où enregistrer le fichier.
- duration=60s — durée de l’enregistrement.
- settings=profile — niveau de détail (default, profile, continuous).
Visualiser les résultats
Pour analyser le fichier .jfr, utilisez JDK Mission Control (JMC) :
- Téléchargez JMC : jdk.java.net/jmc
- Ouvrez le fichier recording.jfr.
- Étudiez les graphiques, les méthodes « chaudes », les pauses GC et l’activité des threads.
Exemple : capturer la « boîte noire »
- Lancez l’application avec JFR (voir la commande ci-dessus).
- Ouvrez JDK Mission Control, chargez le fichier d’enregistrement.
- Évaluez les points chauds CPU/mémoire, la fréquence des collectes de déchets et le nombre de threads actifs.
4. Pratique : surveiller une application
import java.util.ArrayList;
import java.util.List;
public class MonitoringExample {
public static void main(String[] args) throws InterruptedException {
List<byte[]> memory = new ArrayList<>();
for (int i = 0; i < 50; i++) {
memory.add(new byte[2 * 1024 * 1024]); // 2 Mo
Thread.sleep(500);
}
// On lance un thread
new Thread(() -> {
while (true) {
try {
Thread.sleep(1000);
System.out.println("Le thread en arrière-plan fonctionne...");
} catch (InterruptedException e) {
break;
}
}
}).start();
Thread.sleep(20000); // Garder l’application ouverte pour la surveillance
}
}
Actions :
- Lancez le programme.
- Ouvrez VisualVM, trouvez le processus, regardez le graphique de la mémoire et les threads.
- Essayez d’effectuer un heap dump et un thread dump.
- Pour les avancés : démarrez avec JFR et consultez les résultats dans JMC.
5. Points utiles
Tableau comparatif des outils de surveillance
| Outil | Cas d’usage | Comment le lancer | Particularités |
|---|---|---|---|
| JConsole (JMX) | Métriques de base de la JVM, threads, GC | |
Simple, inclus dans le JDK |
| VisualVM | Surveillance, profilage, heap dump | |
Graphiques, analyse mémoire, CPU |
| Java Flight Recorder | Analyse approfondie des événements de la JVM | |
Analyse dans JMC, « boîte noire » |
| JDK Mission Control | Visualisation des fichiers JFR | application séparée | Analytique détaillée, rapports |
Recommandations
- Surveillez non seulement en production, mais aussi en phase de test. Vous détecterez plus tôt les fuites mémoire et les threads « bloqués ».
- Le heap dump, ce n’est pas douloureux ! Réalisez un dump mémoire en cas de suspicion de fuite et étudiez-le dans VisualVM.
- N’ayez pas peur d’expérimenter avec JFR. Même si tout n’est pas clair au début, les événements et les graphiques aideront à trouver les goulots d’étranglement.
- JMX peut être utilisé par programmation. Par exemple, pour envoyer des métriques vers Prometheus/Grafana.
- Le profilage n’est pas fait pour tourner en permanence. Activez les profileurs de façon ciblée, sinon l’application peut ralentir.
6. Erreurs courantes lors de la surveillance de la JVM
Erreur n° 1 : ne pas surveiller du tout. Beaucoup de débutants pensent que si l’application « fonctionne », alors tout va bien. En réalité, les problèmes de mémoire et de threads se manifestent souvent sous charge ou avec le temps. N’hésitez pas à ouvrir VisualVM/JConsole au moins périodiquement.
Erreur n° 2 : effectuer un heap dump sur de grosses applications sans préparation. Un heap dump d’une grande application peut peser des gigaoctets et « geler » le processus pendant plusieurs secondes. Faites-le en environnement de test ou pendant les heures creuses si l’on parle de production.
Erreur n° 3 : ignorer les indicateurs du GC et des threads. Une part constamment élevée du temps passée dans le GC est un signal d’alerte ! Et si le nombre de threads augmente de manière stable — cherchez une fuite de threads.
Erreur n° 4 : ne pas analyser les résultats de la surveillance. Se contenter d’ouvrir VisualVM ne suffit pas. Regardez quels objets occupent la mémoire, quelles méthodes « dévorent » le CPU, pourquoi des deadlocks apparaissent. Analysez les stack traces et leurs causes.
Erreur n° 5 : utiliser des profileurs en production sans comprendre. Le profilage peut considérablement ralentir l’application. Activez-le uniquement pour le diagnostic, pas « en continu ».
GO TO FULL VERSION