Comment lire un thread dump JVM

Collez la sortie de jstack ou de jcmd Thread.print, ou ouvrez un fichier .txt ou .log, puis appuyez sur Analyser localement. Le dump est lu dans ce navigateur : le résumé compte les threads par java.lang.Thread.State, la carte du dessous classe les frames de pile qui reviennent, et les constats nomment les threads qui attendent un verrou détenu par un autre.

Un exemple de 13 threads et 4,3 Ko est ressorti en RUNNABLE 4, WAITING 3, BLOCKED 2, TIMED_WAITING 2 et UNKNOWN 2, avec java.base/java.lang.Thread.sleep(Native Method) comme frame le plus fréquent (3 threads) et deux threads HTTP en attente du moniteur que tenait cache-writer. Rien n’est téléversé et aucune copie du dump n’est conservée.

  1. Collez le dump dans la zone ou déposez un fichier .txt ou .log dessus. La sortie de jstack, de jstack -l et de jcmd <pid> Thread.print convient ; le nom du fichier reste à côté de la zone et disparaît dès que vous collez autre chose.
  2. Appuyez sur Analyser localement. Le résumé affiche une ligne par nom d’état, la carte du dessous liste les douze frames les plus fréquents avec leur nombre, et les deux se remplissent dans la même passe.
  3. Lisez la liste des constats : un interblocage Java est signalé une fois, puis détaillé en threads qui s’attendent mutuellement, et un verrou attendu par un thread alors qu’un autre le détient est nommé des deux côtés.
  4. Reprenez le résultat avec Copier, ou appuyez sur Télécharger pour un rapport texte nommé d’après le fichier chargé (thread-dump-analysis.txt si vous avez collé le dump). Le rapport contient les comptes, le tableau des états, les frames principaux et les constats, pas le dump collé.
  5. Effacer vide la zone, les tableaux et les constats et remet le texte d’attente ; ensuite la page ne conserve rien.

Ce que disent les tableaux et les constats

Ce que l’analyseur lit

Seul du texte est analysé, et seulement sous les formes qu’écrit un dump JVM : les en-têtes de thread (un nom entre guillemets suivi de prio=, tid= ou nid=), les lignes java.lang.Thread.State, les frames at et les lignes waiting to lock / locked / parking to wait for ajoutées par jstack -l. Les threads de la VM sont imprimés sans ligne d’état : ils se retrouvent donc dans la ligne UNKNOWN, comme deux des treize de l’exemple ci-dessus.

Le rapport d’interblocage que jstack ajoute après la liste des threads est lu comme un rapport, pas comme des threads supplémentaires : un dump de trois threads avec un interblocage reste à trois threads, et le rapport donne un constat plus une ligne par paire en attente.

Comment les nombres sont comptés

Chaque frame de chaque thread compte, et pas seulement les trois plus internes, car un frame partagé plus bas dans la pile est exactement la marque d’un chemin d’appel répété. Dans un exemple de 24 threads dont le cinquième frame est java.base/java.lang.reflect.Method.invoke(Method.java:568), ce frame apparaît 18 fois dans le dump et dans le tableau.

Une corrélation de verrou exige les deux moitiés dans le même dump : la ligne waiting to lock <id> d’un thread et la ligne locked <id> d’un autre. Les verrous dont le détenteur n’est pas dans le fichier — dump tronqué ou jstack sans -l — restent comptés comme attentes, mais rien n’est affirmé sur qui les détient.

La taille n’est pas une limite pratique : un dump de 240 threads et 92 Ko est revenu avec 240 threads, 6 bloqués sur un même moniteur et trois frames comptés 240 fois chacun, parce que le travail se fait sur cette machine.

Limites et compatibilité

Un journal de crash HotSpot (hs_err_pid*.log) énumère les threads Java mais ne contient aucune ligne java.lang.Thread.State : la page le dit plutôt que d’afficher des tableaux vides. Tout autre texte sans un seul en-tête de thread reçoit la même réponse, et une zone vide donne un avertissement plutôt qu’un résultat.

Un seul dump est lu à la fois. L’analyseur ne se connecte pas à une JVM, ne peut pas échantillonner un processus en cours et ne surveille pas les modifications d’un fichier ; pour une vue en direct, Flight Recorder ou un profileur est le bon outil.

Noms d’état, signatures de frame et identifiants de verrou sont imprimés exactement comme le dump les écrit, en anglais, parce que ce sont des données ; les libellés autour suivent la langue de la page.

Outils récents :