Java Thread Dump – VisualVM, jstack, kill -3, jcmd

Java Thread dump is een lijst van alle actieve threads in de JVM.

Java Thread Dump

Java thread dump is zeer nuttig bij het analyseren van knelpunten in de toepassing en deadlock-situaties. Hier zullen we meerdere manieren leren waarop we een thread dump kunnen genereren voor een Java-programma. Deze instructies zijn geldig voor *nix-besturingssystemen, maar op Windows kunnen de stappen enigszins verschillen.

  1. VisualVM Profiler: Als u een toepassing analyseert op traagheid, moet u een profiler gebruiken. We kunnen heel eenvoudig een thread dump genereren voor elk proces met behulp van de VisualVM-profiler. U hoeft alleen met de rechtermuisknop op het draaiende proces te klikken en op de optie “Thread Dump” te klikken om het te genereren.
  2. jstack: Java wordt geleverd met de jstack-tool waarmee we een thread dump kunnen genereren voor een Java-proces. Dit is een tweestapsproces.
    1. Vind de PID van het Java-proces met het ps -eaf | grep java-commando
    2. Voer de jstack-tool uit als jstack PID om de thread dump-uitvoer naar de console te genereren. U kunt de thread dump-uitvoer ook toevoegen aan een bestand met het commando “jstack PID >> mydumps.tdump
  3. We kunnen het kill -3 PID-commando gebruiken om de thread dump te genereren. Dit is iets anders dan andere manieren om een thread dump te genereren. Wanneer het kill-commando wordt uitgevoerd, wordt de thread dump naar de systeemuitvoer van het programma gegenereerd. Als het een Java-programma met de console als systeemuitvoer is, wordt de thread dump op de console afgedrukt. Als het Java-programma een Tomcat-server is met systeemuitvoer als catalina.out, wordt de thread dump in het bestand gegenereerd.
  4. Java 8 heeft het hulpprogramma jcmd geïntroduceerd. Je moet dit gebruiken in plaats van jstack als je Java 8 of hoger gebruikt. Het commando om een thread dump te genereren met jcmd is jcmd PID Thread.print.

Dit zijn vier verschillende manieren om een thread dump in Java te genereren. Meestal geef ik de voorkeur aan het jstack- of jcmd-commando om een thread dump te genereren en te analyseren. Let op, welke methode je ook kiest, de thread dump zal altijd hetzelfde zijn.

Voorbeeld van Java Thread Dump

In mijn laatste post heb ik uitgelegd over Java Timer, hier is een thread dump gegenereerd voor hetzelfde programma.

2012-12-26 22:28:39
Full thread dump Java HotSpot(TM) 64-Bit Server VM (23.5-b02 mixed mode):

"Attach Listener" daemon prio=5 tid=0x00007fb7d8000000 nid=0x4207 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Timer-0" daemon prio=5 tid=0x00007fb7d4867000 nid=0x5503 waiting on condition [0x00000001604d9000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at com.journaldev.threads.MyTimerTask.completeTask(MyTimerTask.java:19)
	at com.journaldev.threads.MyTimerTask.run(MyTimerTask.java:12)
	at java.util.TimerThread.mainLoop(Timer.java:555)
	at java.util.TimerThread.run(Timer.java:505)

"Service Thread" daemon prio=5 tid=0x00007fb7d482c000 nid=0x5303 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" daemon prio=5 tid=0x00007fb7d482b800 nid=0x5203 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" daemon prio=5 tid=0x00007fb7d4829800 nid=0x5103 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=5 tid=0x00007fb7d4828800 nid=0x5003 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=5 tid=0x00007fb7d4812000 nid=0x3f03 in Object.wait() [0x000000015fd26000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x0000000140a25798> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
	- locked <0x0000000140a25798> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
	at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)

"Reference Handler" daemon prio=5 tid=0x00007fb7d4811800 nid=0x3e03 in Object.wait() [0x000000015fc23000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x0000000140a25320> (a java.lang.ref.Reference$Lock)
	at java.lang.Object.wait(Object.java:503)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
	- locked <0x0000000140a25320> (a java.lang.ref.Reference$Lock)

"main" prio=5 tid=0x00007fb7d5000800 nid=0x1703 waiting on condition [0x0000000106116000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at com.journaldev.threads.MyTimerTask.main(MyTimerTask.java:33)

"VM Thread" prio=5 tid=0x00007fb7d480f000 nid=0x3d03 runnable 

"GC task thread#0 (ParallelGC)" prio=5 tid=0x00007fb7d500d800 nid=0x3503 runnable 

"GC task thread#1 (ParallelGC)" prio=5 tid=0x00007fb7d500e000 nid=0x3603 runnable 

"GC task thread#2 (ParallelGC)" prio=5 tid=0x00007fb7d5800000 nid=0x3703 runnable 

"GC task thread#3 (ParallelGC)" prio=5 tid=0x00007fb7d5801000 nid=0x3803 runnable 

"GC task thread#4 (ParallelGC)" prio=5 tid=0x00007fb7d5801800 nid=0x3903 runnable 

"GC task thread#5 (ParallelGC)" prio=5 tid=0x00007fb7d5802000 nid=0x3a03 runnable 

"GC task thread#6 (ParallelGC)" prio=5 tid=0x00007fb7d5802800 nid=0x3b03 runnable 

"GC task thread#7 (ParallelGC)" prio=5 tid=0x00007fb7d5803800 nid=0x3c03 runnable 

"VM Periodic Task Thread" prio=5 tid=0x00007fb7d481e800 nid=0x5403 waiting on condition 

JNI global references: 116

Thread dump is de lijst van alle threads, elke invoer toont informatie over de thread, inclusief het volgende in de volgorde van verschijnen.

  1. Thread Naam: Naam van de Thread
  2. Thread Prioriteit: Prioriteit van de thread
  3. Thread ID: Vertegenwoordigt de unieke ID van de Thread
  4. Thread Status: Geeft de huidige thread status weer, bijvoorbeeld RUNNABLE, WAITING, BLOCKED. Bij het analyseren van een deadlock, zoek naar de geblokkeerde threads en de resources waarop ze proberen een slot te verkrijgen.
  5. Thread callstack: Biedt cruciale stackinformatie voor de thread. Dit is de plaats waar we de locks kunnen zien die zijn verkregen door de Thread en of deze wacht op een bepaald slot.

Dat is alles voor de thread dump in Java.

Source:
https://www.digitalocean.com/community/tutorials/java-thread-dump-visualvm-jstack-kill-3-jcmd