Diagnostics Java
Choisir l'outil le plus léger qui répond à la question, en commençant par le symptôme.
Niveaux de permission (les respecter)
| Niveau | Outils | Règle |
|---|---|---|
| 1. Lecture seule | jps -l, jcmd <pid> help/VM.version/VM.flags/Thread.print, jstat, jstack, lecture de logs |
Peut s'exécuter après avoir énoncé la commande exacte. Les histogrammes de classe (jcmd <pid> GC.class_histogram, jmap -histo, jmap -histo:live) ne sont PAS Niveau 1 : ils exécutent une inspection de heap à un safepoint et peuvent mettre en pause les threads de l'application sur un grand heap, donc les traiter comme Niveau 2 (consentement, overhead déclaré). Les formes par défaut et -histo:live forcent en outre un full GC ; -all=true / jmap -histo sautent le full GC mais mettent toujours en pause pendant le scan (et comptabilisent les objets inaccessibles). |
| 2. Enregistrement / attachement | JFR (JFR.start, -XX:StartFlightRecording), async-profiler, NMT (-XX:NativeMemoryTracking), activation de logs GC |
Demande le consentement de l'utilisateur. Énoncer la durée et l'overhead attendu (profil par défaut JFR environ 1-2 % ; async-profiler dépend du mode ; résumé NMT environ 5-10 %, détail plus) avant d'exécuter. |
| 3. Intrusif / sensible | Heap dumps (GC.heap_dump, jmap -dump), jhsdb, commandes qui affichent les arguments JVM ou les propriétés système (jps -v/-lv/-m, jcmd seul, VM.system_properties, VM.command_line, jinfo, ps aux sur un processus Java ; elles peuvent exposer des secrets, rédiger la sortie), JDWP avec suspend, toute chose en production |
Demande le consentement explicite, un chemin cible énoncé, une vérification d'espace disque libre (un dump fait environ la taille du heap utilisé), et une pause énoncée. Les heap dumps contiennent des secrets (mots de passe, tokens, données personnelles). Ne jamais les partager ni les télécharger ; la rédaction n'est PAS une sauvegarde fiable. Analyser localement et supprimer après. |
Ne jamais exécuter les commandes Niveau 2 ou Niveau 3 sur la production à moins que l'utilisateur l'instruise explicitement. Exécuter les outils de diagnostic en tant que même utilisateur OS que la JVM cible. Préférer reproduire en dev ou staging.
Tableau de décision
| Symptôme | Première étape | Ensuite | Référence |
|---|---|---|---|
| CPU élevée | Thread dumps x3 (Niveau 1) + top -H pour mapper les hot native thread ids vers nid |
Flame graph CPU JFR ou async-profiler (Niveau 2) | threads, jfr, async-profiler |
| Fuite mémoire / OOM | jstat -gcutil, GC.class_histogram -all=true deux fois, minutes d'écart (Niveau 2 : pause safepoint même avec -all=true ; sans cela un full GC aussi ; obtenir consentement en production) |
Heap dump + Eclipse MAT (Niveau 3) ou JFR OldObjectSample (Niveau 2) | heap, gc |
| Démarrage lent | -Xlog:class+load, rapports de démarrage/condition du framework, logs horodatés |
JFR depuis le démarrage, async-profiler wall-clock | jfr, async-profiler |
| Deadlock / famine de threads | jcmd <pid> Thread.print (signale les deadlocks), comparer les dumps dans le temps |
Virtual threads : Thread.dump_to_file |
threads |
| Pauses GC | Log GC (-Xlog:gc*) et jstat -gc |
Événements GC JFR ; accorder le collector/heap | gc |
| Croissance native memory (RSS augmente, heap ne change pas) | Comparer RSS vs heap ; activer NMT, jcmd VM.native_memory baseline / summary.diff (Niveau 2) |
async-profiler nativemem ou outils allocator |
nmt, containers |
| Requêtes lentes | Tracing/metrics et logs d'abord ; Actuator ou Dev UI (voir ci-dessous) | JFR (événements socket/file/lock), async-profiler wall-clock | jfr, async-profiler |
| Crash / hang JVM, aucun outil ne répond | hs_err_pid*.log, core dump |
jhsdb (Niveau 3) |
basics |
Commencer par bases jps/jcmd pour identifier la JVM cible et confirmer quelle version JDK s'exécute.
Flux de travail
- Capturer le symptôme précisément (quand, à quelle fréquence, depuis quel changement, version JDK, limites du conteneur).
- Choisir le niveau nécessaire ; énoncer la commande, son overhead et l'emplacement de sortie, et obtenir le consentement pour Niveau 2/3.
- Collecter les données dans un répertoire dédié, avec horodatages. Préférer plusieurs échantillons à un seul.
- Former une hypothèse à partir des données, puis confirmer avec une deuxième source (par exemple un thread dump plus un flame graph).
- Corriger, re-mesurer avec la même méthode, et nettoyer les artefacts (dumps, recordings).
Aperçus au niveau application (optionnel)
Les outils JDK voient la JVM ; certaines questions (quel endpoint, quelle requête SQL, quel bean) sont plus faciles au niveau application. Options optionnelles, par ordre de préférence :
- Spring Boot Actuator (
metrics,health,loggers,httpexchanges) et Quarkus Dev UI / métriques Micrometer sont intégrés et ne demandent aucun outil supplémentaire. Exposer les endpoints Actuator minimalement ; pourheapdumpetthreaddump, suivre la politique dans la skillspring-observability: ne jamais les exposer sur HTTP public ; la seule exception est une fenêtre temporaire, consentie par l'utilisateur, avec authentification, TLS et restriction réseau, supprimée après. - BootUI (https://github.com/jdubois/boot-ui , https://www.julien-dubois.com/boot-ui/) : une console développeur locale uniquement avec serveur MCP opt-in pour Spring Boot et Quarkus. Optionnel. Sa skill peut être installée avec
gh skill install jdubois/boot-ui skills/bootui.
Si BootUI est envisagé :
- Demander le consentement de l'utilisateur avant d'ajouter une dépendance ou d'installer la skill.
- L'utiliser dans un profil local/dev uniquement ; ne jamais l'exposer sur un réseau, et ne jamais activer ses endpoints de heap dump, thread dump ou serveur MCP en production.
- Vérifier d'abord la capacité et la version (lire son README pour les versions Spring Boot / Quarkus supportées) au lieu d'assumer les fonctionnalités.
Suivre la documentation propre du projet pour l'usage ; cette skill ne la reproduit pas.
Conteneurs
Voir containers pour attacher des outils à l'intérieur des conteneurs, -XX:MaxRAMPercentage, et limites de mémoire cgroup.
Références
- Bases jps / jcmd
- Thread dumps et deadlocks
- Heap, histogrammes, Eclipse MAT
- Logs GC et jstat
- JFR et JDK Mission Control
- async-profiler
- Native Memory Tracking
- Conteneurs
- Investigation basée sur debugger : la skill
java-debugging.
Docs officielles (les préférer à cette skill pour le JDK en usage ; remplacer 21 par votre version) : jcmd https://docs.oracle.com/en/java/javase/21/docs/specs/man/jcmd.html, jfr https://docs.oracle.com/en/java/javase/21/docs/specs/man/jfr.html, guide JFR https://docs.oracle.com/en/java/javase/21/jfr/introduction-jdk-flight-recorder.html, guide de dépannage https://docs.oracle.com/en/java/javase/21/troubleshoot/, releases async-profiler https://github.com/async-profiler/async-profiler/releases.