Explain Codes LogoExplain Codes Logo

How to get a thread and heap dump of a Java process on Windows that's not running in a console

java
heap-dump
thread-dump
visualvm
Nikita BarsukovbyNikita Barsukov·Aug 13, 2024
TLDR

Concisely put, a thread dump can be nabbed by running jstack -l <PID> and a heap dump can be gathered via jmap -dump:live,file=heapDump.hprof <PID>. Make sure to replace <PID> with your actual Java process ID. This ID can be located using either Windows Task Manager or the Java process status tool also known as jps. Remember to save these dumps to files as these can help with detailed analysis later.

// I said no chainsaw -rt3621 jstack -l <PID> > threadDump.txt // Digitally excavating the heap -bs233 jmap -dump:live,file=heapDump.hprof <PID>

Locating the elusive PID

Being able to grab a Java application's thread and heap dump is valuable, but finding that pesky process ID (PID) is the first hurdle to cross. Task Manager is the quick and simple way to do this, however, Resource Monitor and jps provide more holistic ways to scan for Java processes.

// Maury Povich, you ARE the PID! -unknown jps -l

Diving into thread dumps

A thread dump is a snapshot of all threads in the JVM at a given moment, ideal for diagnosing deadlocks. You can obtain these using jstack. Alternatively, on Unix systems, you can also get them by sending the SIGQUIT signal by typing (kill -3 <PID>). But when on Windows, jstack is your trusty sidekick.

Automatic dump generation

Java provides an in-built mechanism to automatically trigger a heap dump, in the form of the -XX:+HeapDumpOnOutOfMemoryError flag. Pair this with the -XX:HeapDumpPath=/path/to/dump flag, and you can declare exactly where you want the dumps.

// autodump inception... when you run out of memory while remembering! -kn16 java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heapDumps -jar your-application.jar

Real-time monitoring

Java comes with some pretty impressive GUIs that allow one to see inside the living, breathing JVM. Running the jconsole command or using VisualVM avails us to a host of useful features with which we can generate thread and heap dumps. These tools not only provide those aforementioned dumps but offer real-time live profiling capability.

// the art of zen debugging -anonymous jconsole -J-Djava.awt.headless=true

So, you got a heap dump

Good job grabbing the heap dump, but now you gotta sift through this massive .hprof file. Use Eclipse Memory Analyzer Tool (MAT), use it to identify memory leaks and figure out what's using most memory. Remember, your memory is precious—don't let runaway processes hog it!

Unleashing the power of VisualVM

VisualVM is basically a Swiss army knife for Java profiling. It bundles in lots of JDK command-line tools into an easy-to-use GUI that not only allows you to take heap and thread dumps, but also track memory usage over time, and monitor thread states.

Extending VisualVM

One does not merely use the default features in VisualVM. Using plugins, you can supercharge VisualVM with capabilities beyond what it offers out of the box. For instance, the Visual GC plugin visualizes garbage collection in real time, which is perfect for tracking your application's memory usage trends.

// It looks fancy! -iw04 visualvm --plugins install org-netbeans-visualvm-visualgc

Monitoring changes

Before you embark on any major operation, be sure to capture heap and thread dumps. Do the same when the operation is done, and compare the two. Analyzing these differences can provide insights into what could be causing performance or behavior shifts, helping you proactively solve potential issues.

// You are here: the wonderful world of debugging -сz99 visualvm --openpid <PID_before_OP> --openpid <PID_after_OP>