
Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:
Once the early-adopter seats are all used, the price will go up and stay at $33/year.
Last updated: May 11, 2024
In this tutorial, we’ll discuss various ways to capture the thread dump of a Java application.
A thread dump is a snapshot of the state of all the threads of a Java process. The state of each thread is presented with a stack trace, showing the content of a thread’s stack. A thread dump is useful for diagnosing problems, as it displays the thread’s activity. Thread dumps are written in plain text, so we can save their contents to a file and look at them later in a text editor.
In the next sections, we’ll go through multiple tools and approaches to generate a thread dump.
The JDK provides several utilities that can capture the thread dump of a Java application. All of the utilities are located under the bin folder inside the JDK home directory. Therefore, we can execute these utilities from the command line as long as this directory is in our system path.
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. Alternatively, we can redirect its output to a file.
Let’s take a look at the basic command syntax for capturing a thread dump using jstack:
jstack [-F] [-l] [-m] <pid>
All the flags are optional. Let’s see what they mean:
Let’s put this knowledge to use by capturing a thread dump and redirecting the result to a file:
jstack 17264 > /tmp/threaddump.txt
Remember that we can easily get the pid of a Java process by using the jps command.
Java Mission Control (JMC) is a GUI tool that collects and analyzes data from Java applications. After we launch JMC, it displays the list of Java processes running on a local machine. We can also connect to remote Java processes through JMC.
We can right-click on the process and click on the “Start Flight Recording” option. After this, the Threads tab shows the Thread Dumps:
jvisualvm is a tool with a graphical user interface that lets us monitor, troubleshoot, and profile Java applications. The GUI is simple, but very intuitive and easy to use.
One of its many options allows us to capture a thread dump. If we right-click on a Java process and select the “Thread Dump” option, the tool will create a thread dump and open it in a new tab:
As of JDK 9, Visual VM isn’t included in the Oracle JDK and Open JDK distributions. Therefore, if we’re using Java 9 or newer versions, we can get the JVisualVM from the Visual VM open source project site.
jcmd is a tool that works by sending command requests to the JVM. Although powerful, it doesn’t contain any remote functionality; we have to use it in the same machine where the Java process is running.
One of its many commands is Thread.print. We can use it to get a thread dump just by specifying the pid of the process:
jcmd 17264 Thread.print
jconsole lets us inspect the stack trace of each thread. If we open jconsole and connect to a running Java process, we can navigate to the Threads tab and find each thread’s stack trace:
As it turns out, there are many ways to capture a thread dump using JDK utilities. Let’s take a moment to reflect on each and outline their pros and cons:
In enterprise application servers, only the JRE is installed for security reasons. Thus, we can’t use the above-mentioned utilities, as they’re part of JDK. However, there are various command-line alternatives that let us capture thread dumps easily.
The easiest way to capture a thread dump in Unix-like systems is through the kill command, which we can use to send a signal to a process using the kill() system call. In this use case, we’ll send it the -3 signal.
Using our same pid from earlier examples, let’s take a look at how to use kill to capture a thread dump:
kill -3 17264
This way the signal-receiving Java process will print the thread dump on the standard output.
If we run the Java process with the following combination of tuning flags, then it’ll also redirect the thread dump to the given file:
-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=~/jvm.log
Now if we send the -3 signal, in addition to the standard output, the dump will be available at ~/jvm.log file.
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 the CTRL and Break keys together.
It’s worth noting that, on some keyboards, the Break key isn’t available. Therefore, in such cases, a thread dump can be captured using the CTRL, SHIFT, and Pause keys together.
Both of these commands print the thread dump to the console.
The last approach we’ll discuss in this article is using JMX. We’ll use ThreadMxBean to capture the thread dump. Let’s see it in code:
private static String threadDump(boolean lockedMonitors, boolean lockedSynchronizers) {
StringBuffer threadDump = new StringBuffer(System.lineSeparator());
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) {
threadDump.append(threadInfo.toString());
}
return threadDump.toString();
}
In the above program, we’re performing several steps:
In this article, we learned multiple ways to capture a thread dump.
First, we discussed various JDK Utilities, and then the command-line alternatives. Finally, we concluded with the programmatic approach using JMX.