How to get and analyze thread dumps in Java?



Introduction

A Java thread dump is a snapshot what every thread in the JVM is doing at a particular point in time. Each thread in the JVM is listed with it’s name and id, it’s current state and the Java call stack showing what monitor it has locked or is waiting on. This is especially useful if your Java application sometimes seems to hang when running under load, as an analysis of the dump will show where the threads are stuck, either by deadlock or other thread contention.


How to get a thread dump in Java?

Step 1: Get the PID of your Java process

 

If this doesn’t work or you still cannot find your Java process, (path not set, JDK not installed, or older Java version), use

  • UNIX, Linux, and Mac OS X:
ps -el | grep SleepingThread
  • Windows:
Press Ctrl+Shift+Esc to open the task manager and find the PID of the Java process

Step 2: Request a thread dump from the JVM

jstack

If installed/available, we recommend using the jstack tool. It prints thread dumps to the command line console.

To obtain a thread dump using jstack, run the following command:

jstack -l <pid>

You can output consecutive thread dumps to a file by using the console output redirect/append directive:

jstack -l <pid> >> threaddumps.log

How to Analyze Thread Dumps in Java?

package com.example.TestApp;public class SleepingThread   {          public static void main( String[] args ) throws InterruptedException          {                 System.out.println( "Hello World!" );                  Thread.sleep(50000);                  System.out.println( "End of Main Thread" );          }     }

Thread Dump for MainThread

"main" #1 prio=5 os_prio=31 tid=0x00007f970d002000 nid=0x2603 waiting on condition [0x000070000061b000]     java.lang.Thread.State: TIMED_WAITING (sleeping)   at java.lang.Thread.sleep(Native Method)   at com.example.TestApp.SleepingThread.main(SleepingThread.java:16)     Locked ownable synchronizers:   - None


class Producer implements Runnable {    public void run() {        try {         synchronized(this) {                    wait();                    System.out.println( "End of Producer1 Thread" );            }              }catch(InterruptedException e) {               }  }}

Thread Dump for Producer

"Thread-0" #10 prio=5 os_prio=31 tid=0x00007f970f005000 nid=0xa903 in Object.wait() [0x00007000019d7000]java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000076abb9440> (a com.example.TestApp.Producer1) at java.lang.Object.wait(Object.java:502) at com.example.TestApp.Producer1.run(SleepingThread.java:29) - locked <0x000000076abb9440> (a com.example.TestApp.Producer1) at java.lang.Thread.run(Thread.java:748)Locked ownable synchronizers: - None


class Producer implements Runnable {    public void run() {        try {         synchronized(this) {                    wait(2000);                    System.out.println( "End of Producer1 Thread" );            }              }catch(InterruptedException e) {               } }}

Thread Dump for Producer: with time

Thread-0" #10 prio=5 os_prio=31 tid=0x00007fc352872000 nid=0x5603 in Object.wait() [0x0000700010434000]   java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000076abb9450> (a com.example.TestApp.Producer1) at com.example.TestApp.Producer1.run(SleepingThread.java:29) - locked <0x000000076abb9450> (a com.example.TestApp.Producer1) at java.lang.Thread.run(Thread.java:748)   Locked ownable synchronizers: - None


Source Code: 

package com.example.TestApp;public class SleepingThread{    public static void main( String[] args ) throws InterruptedException    {        System.out.println( "Hello World!" );        Thread t1 = new Thread(new Producer());        t1.start();        Thread.sleep(50000);        t1.join();         System.out.println( "End of Main Thread" );    }}class Producer implements Runnable {    public void run() {        try {         synchronized(this) {                    wait(20000);                    System.out.println( "End of Producer1 Thread" );            }              } catch(InterruptedException e) {     }  }}