Skip to main content

How to Capture and Analyze a Heap Dump

In this post, we'll dive into the practical aspects of capturing and analyzing Java heap dumps. This article continues from our previous deep dive, Java Dumps Uncovered: When to Use Thread Dump, Heap Dump, or Core Dump — where we explored the scenarios in which each type of dump is appropriate.


Quick Summary

Refer to the section on When to Take a Heap Dump from the previous post to understand the right circumstances for capturing heap dumps — such as frequent OutOfMemoryErrors or excessive memory retention issues.


Ways to Capture a Heap Dump

There are several ways to generate a heap dump in Java. In this post, we'll demonstrate these using a sample Java application that consumes significant memory via ArrayList, HashMap, and other objects. You can find the sample code in this GitHub Gist.

Before you can capture a heap dump, you'll need to identify the Java process ID (PID). You can do this using either of the following commands:

$ jps

or

$ ps aux | grep java

Once you have the PID, you're ready to capture the heap dump using one of the methods below.


1) Automatic Capture (Best Practice)

Add the following options to your JVM arguments:

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/path/to/dump

This is the most reliable approach since memory issues like OutOfMemoryError can occur unpredictably in production environments. By enabling this option, the JVM will automatically generate a heap dump at the moment the error occurs — ensuring you don’t miss critical debugging information.

Example:

$ java -XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath="heapdump_$(echo $$).hprof" \
HeapDumpExample

2) Using jcmd (Recommended)

A flexible and efficient way to manually trigger heap dumps:

$ jcmd <PID> GC.heap_dump heapdump_using_jcmd.hprof

This method is fast, doesn't require a JVM restart, and is ideal for capturing heap dumps on demand. The heap dump will be generated in the application's working directory, no matter where you run the command from.


3) Using jmap

Another command-line utility provided with the JDK:

$ jmap -dump:format=b,file=heapdump_using_jmap.hprof <PID>

This tool is effective but may be slower or less reliable on newer JVM versions compared to jcmd. With this method, the heap dump is generated in the directory where the command is executed.


4) Using VisualVM (Interactive)

For those who prefer a GUI-based approach:

  • Launch VisualVM

  • Select the running Java application

  • Right-click on it and choose Heap Dump

  • In the analysis pane, click View All under "Classes by Size of Instances"

  • Choose Dominators from the preset dropdown or click GC Root (top-right corner) to identify the objects holding references in memory

Unlike other methods, VisualVM allows you to inspect and debug heap dumps directly within the tool — no additional software like Eclipse MAT is required.




How to Analyze a Heap Dump:

You can analyze a heap dump using tools like VisualVM or MemoryAnalyzer Tool (MAT). You can either open the .hprof file directly in VisualVM and follow the steps mentioned earlier, or use MAT for a more detailed analysis.

Steps to analyze using MemoryAnalyzer Tool (MAT):

  • Open the MemoryAnalyzer Tool.

  • Go to the File menu and select Open Heap Dump.

  • Browse to the folder and open the .hprof heap dump file.

  • To view the largest objects and understand what they keep alive, click on the Dominator Tree option (refer to the video below).

  • To detect memory leaks and view a system overview, click on the Leak Suspects option (refer to the video below).




Conclusion

Capturing and analyzing heap dumps is a powerful way to diagnose memory-related issues in Java applications. Whether you're troubleshooting an OutOfMemoryError, tracking down memory leaks, or simply understanding memory usage patterns — heap dumps provide invaluable insights.

Among the methods discussed, enabling automatic heap dump generation on OutOfMemoryError is the most fail-safe for production environments. For real-time debugging, tools like jcmd and VisualVM offer flexibility and deeper visibility.

As with any debugging tool, the effectiveness of a heap dump depends on when and how you capture it. Choose the method that best suits your scenario, and always analyze the dump with a clear goal in mind — whether it's finding memory leaks, reducing memory footprint, or improving overall application performance.


Comments

Popular posts from this blog

Java Dumps Uncovered: When to Use Thread Dump, Heap Dump, or Core Dump

Choosing the Right Dump for the Right Problem: Knowing which dump to use in a given situation provides a significant advantage while debugging. In this blog, we’ll explore the differences between Thread Dump, Heap Dump, and Core Dump , how to capture them, and when to use them effectively. Understanding Java Threads and Memory: When a simple Java class with a main method runs, it creates a single thread named "main" , which executes the program. In many cases, this single thread is sufficient. However, for applications handling multiple tasks simultaneously, multiple threads are necessary. For example, a web server like Tomcat would be ineffective if it handled all requests using a single thread. Instead, it creates multiple threads to manage concurrent requests. Alongside threads, Java runtime also requires memory to execute programs, which includes components like the Method Area, Heap, Stack, etc. When to Take a Thread Dump? Imagine running a Tomcat server , and a...

How to Capture and Analyze a Thread Dump

We’ll explore how to  capture a thread dump  and analyze it effectively in this post. This is a continuation of  Java Dumps Uncovered: When to Use Thread Dump, Heap Dump, or Core Dump . Quick Summary A  thread dump  helps determine if a thread is stuck. However, taking a single thread dump isn’t enough—we need  at least two or more dumps  to confirm whether a thread remains in the same state over time. Ways to Capture a Thread Dump There are multiple ways to take a thread dump. We’ll explore each method using a  sample Java program  that creates two threads—one terminating in  30 seconds  and another in  5 minutes . The Java file is available in  this gist . To capture a thread dump, the first step is to  identify the Java process ID (PID) . This can be done using: $ jps or $ ps aux | grep java This command lists all running Java processes. Select the  PID  of the process for which you need the thread dump. ...