Core Java

Java Thread Dump

In this article, we’re going to see a thread dump in Java. What are the tools available to analyze and make our own code to do that?

1. Introduction

A thread dump is a snapshot of the state of all the threads of a Java process. Also, it reveals information about an application’s thread activity that can help us diagnose problems and optimize application and JVM performance.

As an example, thread dumps automatically show the occurrence of a deadlock.

Following, we’ll discuss some tools present in JDK Utilities and create an example on code.

2. Pre-requisites

The minimum recommended Java version to use the article’s tools is JDK 8 (find here), but we can use the most recently released Java version (JDK 15).

Also, I’m using IntelliJ 2020.2 to write and execute the code example, but feel free to use any IDE with support for the versions recommended above.

3. JDK Tools and Utilities

The JDK provides several tools and utilities that can capture the thread dump of a Java application. These tools are located in the bin folder of the JDK home directory.

3.1 jstack

jstack is a command-line JDK utility we can use to capture a thread dump. It takes the PID of a process and displays the thread dump in the console.

Using a terminal, let’s execute the command below to see what options jstack brings:

jstack options

$jstack --help
Usage:
    jstack [-l] 
        (to connect to running process)
    jstack -F [-m] [-l] 
        (to connect to a hung process)
    jstack [-m] [-l]  
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack  does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

The following example executes and save the dump in an output file.

jstack example

$ jstack 9199 > ~/Temp/output.txt

And the beginning of output.txt file.

output file example

2021-01-17 17:47:31
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode):

"Attach Listener" #581 daemon prio=9 os_prio=31 tid=0x00007f9a9ab95000 nid=0x951f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

3.2 Java Mission Control (JMC)

Java Mission Control (JMC) is a GUI tool that collects and analyzes data from Java applications.

For some bug reasons, I recommend to download this JMC version from Oracle to run JMC properly.

With JMC opened, on the left side we can see the Java process that are running on our machine.

Java Thread Dump - jmc browser
JMC Browser

We can right-click on the process and click Start Flight Recording. A pop-up window will appear and we can choose where to save the dump and how much time this record will save.

Java Thread Dump - start flight
Start Flight Recording saving options

After the recording has finished, the windows with details about the process will appear in the JMC

Java Thread Dump - flight recording
Flight recording analysis

By choosing the Outline tab in the left menu, we can see details about the threads.

Thread details

Important note: Java Mission Control requires a commercial license for use in production.

3.3 jvisualvm

Java VisualVM (jvisualvm) is an intuitive graphical user interface that provides detailed information about Java applications while they are running on a specified Java Virtual Machine (JVM).

To use it, just open an terminal and type jvisualvm (JDK 8).

We can start the thread dump just right click in the Java application and choose the option “Thread”.

jvisualvm snapshot

Since JDK 9, jvisualvm is not included in Oracle JDK and OpenJDK distribution. Therefore, if we want to use with JDK 9 or higher versions, we can get it on the Visual VM open source site.

3.4 jcmd

The jcmd utility is used to send diagnostic command requests to the JVM, where these requests are useful for controlling Java Flight Recordings, troubleshoot, and diagnose JVM and Java Applications.

An disadvantage of this tools is that doesn’t contain any remote functionality, so we can only use in the local machine where the Java process is running.

The command Thread.print can be used to thread dump just by passing the PID or main class of the Java process as below:

jcmd example

$ jcmd 59891 Thread.print -> with PID
$ jcmd com.example.javacodegeeks.springboot.SpringbootApplication Thread.print -> with main class

We can also save the dump in an output file as following:

jcmd output file

$ jcmd 59891 Thread.print > ~/Temp/output.txt 

3.5 jconsole

The jconsole graphical user interface is a monitoring tool that complies to the Java Management Extensions (JMX) specification.

Also, jconsole uses the extensive instrumentation of the Java Virtual Machine (Java VM) to provide information about the performance and resource consumption of applications running on the Java platform.

On the terminal, just type jconsole to start the window below where we can choose our Java process to dump:

jconsole connection window

When the connection is stablished, we can see on “Thread” tab all the Java process thread running. Select one to see the current dump on the screen.

jconsole Thread dump

4. Server Command line

In enterprise application servers, only the JRE is installed for security reasons. Therefore, we can not use the above-mentioned tools as they are part of JDK.

However, there are a lot of command-line alternatives that allow us capture thread dumps easily.

4.1 Kill command (Linux/Unix)

The kill command in Linux/Unix systems is the easiest way to capture a thread dump. Using the signal -3 with the kill command ,we’ll send to the Java process an instruction to print the standard thread dump output.

kill command example

$ kill -3 59791

If we run the Java process with the following combination of tuning flags, then it will also redirect the thread dump to the given file:

Java tuning flags

-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=~/output.log

Now if we send the -3 signal, in addition to the standard output, the dump will be available at ~/output.log file.

4.2 Ctrl + Break (Windows)

In Windows operating systems, we can capture a thread dump using the Ctrl and Break key combination. To take a thread dump, navigate to the console used to launch the Java application and press Ctrl+Break keys together.

In some keyboards, the Break key is not available. Therefore, in such cases, a thread dump can be captured using Ctrl, Shift and Pause keys together.

Both of these commands print the thread dump to the console.

5. Capturing Programmatically

Below it’s an example using ThreadMXBean to capture the thread dump.

ThreadMxBean example

private static void threadDump(boolean lockedMonitors, boolean lockedSynchronizers) throws IOException, IOException {
        Path threadDumpFile = Paths.get("ThreadDumpOutput.txt");

        StringBuffer threadDump = new StringBuffer(System.lineSeparator());
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) {
            threadDump.append(threadInfo.toString());
        }
        Files.write(threadDumpFile, threadDump.toString().getBytes());
    }

In the code above we see some steps to dump into a file called ThreadDumpOutuput.txt. Let’s see in detail:

  1. StringBuffer created to manage information fro each thread.
  2. Using ManagementFactory to initialize a ThreadMXBean instance. The ManagementFactory class gets the managed beans for Java platform. Also, ThreadMXBean is the management interface for thread system of the JVM.
  3. Setting lockedMonitors and lockedSynchronizers values to true indicates to capture the synchronizers and all locked monitors in the thread dump.
  4. Finally, insert all data in the StringBuffer and put in the file.

6. Conclusion

In conclusion, we see in this article a few tools to deal with thread dumps in Java. Some of them are easily to work in a friendly interface and mostly part of JDK package.

Further, we can take a look in a simple code example to do our own thread dump into our Java applications.

7. Download the source code

Download
You can download the full source code of this example here: Java Thread Dump

Sergio Lauriano Junior

Sergio is graduated in Software Development in the University City of São Paulo (UNICID). During his career, he get involved in a large number of projects such as telecommunications, billing, data processing, health and financial services. Currently, he works in financial area using mainly Java and IBM technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button