How to capture a Thread dump in Java

In this tutorial, we will learn how to capture a thread dump in Java using different methods depending on the operating system and the environment in which the Java application is running.

A thread dump is a snapshot of the current state of all threads in a Java application. It is useful for diagnosing problems with the application, such as deadlocks, performance issues, and race conditions.

There are several ways to capture a thread dump in Java, depending on the operating system and the environment in which the Java application is running. Here are three common methods:

Using the jstack command line tool

The jstack tool is part of the Java Development Kit (JDK) and can be used to capture a thread dump from a running Java application. To use jstack, you will need to know the process ID of the Java application.

On Linux or macOS, you can use the ps command to find the process ID:

ps aux | grep java

This will list all processes running Java, along with their process IDs. Once you have the process ID, you can use jstack to capture the thread dump:

jstack <process ID> > threaddump.txt

On Windows, you can use the tasklist command to find the process ID:

tasklist | find "java"

Finally, please note that, in many cases, you will need to capture a set of Thread dumps for a comparison. The following sample script will perform a Thread dump every minute and save it to the OUTPUT_FILE variable:

#!/bin/bash

# Set the process ID of the Java application
PROCESS_ID=12345

# Set the output file for the thread dump
OUTPUT_FILE=threaddump.txt

while true
do
  # Capture the thread dump
  jstack $PROCESS_ID >> $OUTPUT_FILE
 
  # Sleep for one minute
  sleep 60
done

Using the ThreadMXBean to generate the dump

To capture a Java thread dump programmatically, you can use the ThreadMXBean interface, which is part of the Java Management Extension (JMX). Here is an example of how to use it:

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

public class ThreadDump {
  public static void main(String[] args) {
    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
    long[] threadIds = threadMXBean.getAllThreadIds();
    ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadIds);
    for (ThreadInfo threadInfo : threadInfos) {
      System.out.println("Thread name: " + threadInfo.getThreadName());
      System.out.println("Thread state: " + threadInfo.getThreadState());
      System.out.println("Thread stack trace: ");
      for (StackTraceElement stackTraceElement : threadInfo.getStackTrace()) {
        System.out.println("  " + stackTraceElement);
      }
    }
  }
}

This code will print the name, state, and stack trace of all threads in the Java application. You can redirect the output to a file if you want to save the thread dump for later analysis.

Alternatively, you can use the HotSpotDiagnosticMXBean to capture a thread dump programmatically. This bean is part of the JDK and provides a method called dumpAllThreads that allows you to capture a thread dump in a single call. Here is an example of how to use it:

import com.sun.management.HotSpotDiagnosticMXBean;

import javax.management.MBeanServer;
import java.io.IOException;
import java.lang.management.ManagementFactory;

public class ThreadDump {
  public static void main(String[] args) throws IOException {
    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy(
        server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
    bean.dumpAllThreads(true, true);
  }
}

This will print the thread dump to the console. You can redirect the output to a file if you want to save the thread dump for later analysis.

Capturing the Thread Dump with Byteman

Byteman is a Java tool that allows you to inject bytecode into a running Java application and to create rules that specify when and where the bytecode should be executed. You can use Byteman to create a thread dump by injecting a rule that triggers a thread dump when a certain condition is met.

You can use this option if you don’t know the exact time when you need to execute the Thread dump. On the other hand, you probably know that you need to capture the Thread dump during a method execution or if an Exception is raised.

Firstly, instrument Byteman as you can read in this article: Introduction to Byteman

Next, create the Byteman rule file. The rule file should contain a rule that triggers a thread dump when a certain condition is met. Here is an example rule that triggers a thread dump when the main method is called:

RULE thread dump
CLASS MyApplication
METHOD main
AT ENTRY
IF true
DO threadDump()
ENDRULE

Save the rule file and start the Java application. When the main method is called, Byteman will trigger a thread dump and print it to the console. You can redirect the output to a file if you want to save the thread dump for later analysis.

Using a Tool like jVisualVM

Every JVM Tool includes the ability to capture a Thread Dump. To mention a few: jVisualVM, jConsole, Java Mission Control.

Let’s see for example how to capture a dump with jVisualVM.

VisualVM is a Java monitoring and profiling tool that allows you to monitor the performance and resource usage of a running Java application. You can use VisualVM to capture a thread dump of a Java application by following these steps:

Start VisualVM from the command line:

visualvm

In the VisualVM window, select the Java application that you want to capture a thread dump for.

how to capture a thread dump in java

Besides, you can also use the Threads tab in the right pane and click the Thread Dump button to capture a the dump.

Conclusion

This article was a walk through how to collect a Thread Dump in Java to analyze and troubleshoot Java applications. After collecting the Thread dump, it’s time to inspect it! Check this article to do that. How to inspect a Thread Dump like a pro