Taking and reading a Java heap dump: jcmd, jmap, HeapDumpOnOutOfMemoryError and Eclipse MAT

A heap dump is a file containing every object in the Java heap, its fields and the references between objects. It is the most precise tool there is for memory problems, and also the heaviest: taking one pauses the application and the file can contain secrets. This guide covers both sides.
Three ways to get a dump
On demand with jcmd
The JDK troubleshooting guide recommends jcmd over the older jmap. The jcmd reference documents GC.heap_dump with a file name argument and three options: -all to include unreachable objects, -gz to compress with a given level, and -overwrite to replace an existing file.
$ jcmd <pid> GC.heap_dump /var/tmp/app-$(date +%Y%m%d-%H%M).hprof
# compressed, fastest level
$ jcmd <pid> GC.heap_dump -gz=1 /var/tmp/app.hprof.gz
Without -all, only live objects are written, which requires a full collection first. That is usually what you want for leak hunting: dead objects are noise. Use -all when you are investigating allocation churn rather than retention.
The path is resolved by the target JVM, not by your shell, so a relative path lands in the JVM's working directory. Use an absolute path on a disk with enough free space.
With jmap
$ jmap -dump:live,format=b,file=/var/tmp/app.hprof <pid>
The result is equivalent; live plays the same role as omitting -all. If a process is hung and does not answer the attach request, the troubleshooting guide points to jhsdb jmap, which uses the Serviceability Agent instead of the attach mechanism.
Automatically on OutOfMemoryError
The most valuable dump is the one taken at the moment of failure. The java launcher reference documents -XX:+HeapDumpOnOutOfMemoryError (disabled by default) and -XX:HeapDumpPath; without a path the file is written to the working directory as java_pid<pid>.hprof.
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/dumps/
-XX:+ExitOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError makes the JVM exit after the first OutOfMemoryError, so an orchestrator restarts a clean instance instead of leaving a damaged one serving traffic. The dump is written before the exit. In a container, point HeapDumpPath at a mounted volume, or the file disappears with the container.
What a dump costs
- A pause. The application is stopped while the heap is walked and written. On a large heap that can take a long time; take dumps from an instance you have removed from the load balancer where possible.
- Disk. An uncompressed dump is roughly the size of the used heap. A 12 GB heap can produce a file of that order.
- Memory to analyse. Analysis tools need a significant amount of RAM themselves. Eclipse MAT's heap is set in
MemoryAnalyzer.iniwith an-Xmxline. - Confidentiality. The dump contains everything in memory: passwords, tokens, personal data, request bodies. Treat it like a database backup: restricted storage, encrypted transfer, deletion after use.
Reading a dump with Eclipse Memory Analyzer
Eclipse Memory Analyzer (MAT) is a free tool that opens HPROF files and builds indexes so that even large dumps can be navigated. On first open it parses the file and writes index files next to it, which makes reopening fast.
Shallow and retained size
Two numbers appear everywhere. Shallow size is the memory of the object itself: its header and fields. Retained size is the memory that would be freed if that object were removed, meaning the object plus everything reachable only through it. A HashMap has a small shallow size and can have an enormous retained size. Leaks are found by retained size.
The views to use, in order
- Leak Suspects report. MAT proposes it on opening. It points at objects with a large share of the retained heap and shows the accumulation point. Treat it as a starting hypothesis, not a verdict.
- Histogram. Instances and shallow size per class. Sort by retained size (MAT computes it on request) to see which classes matter.
- Dominator tree. Objects ordered by retained size, organised so that each object's children are the objects it keeps alive. The top entries are where the memory is.
- Path to GC Roots. From a suspicious object, choose Path to GC Roots → exclude weak/soft references. The path shows exactly which chain of fields keeps it alive. See GC roots and memory leaks for how to interpret the root types.
Queries
MAT includes an SQL-like Object Query Language. A query that lists large byte arrays, for example:
SELECT a, a.@length FROM byte[] a WHERE a.@length > 1048576
Comparing two dumps
One dump shows what is big. Two dumps taken some time apart show what is growing, which is the real definition of a leak. MAT can compare histograms between dumps; the classes with the largest increase in instance count are the place to start.
Analysing on a server without a desktop
Large dumps are often easier to analyse where they are produced. MAT ships a headless script that parses a dump and generates reports as zipped HTML:
$ ./ParseHeapDump.sh /var/dumps/java_pid4242.hprof org.eclipse.mat.api:suspects
$ ./ParseHeapDump.sh /var/dumps/java_pid4242.hprof org.eclipse.mat.api:top_components
The index files produced by the headless run can be copied together with the dump and opened later in the desktop tool without re-parsing.
Lighter alternatives first
Not every memory question needs a full dump:
jcmd <pid> GC.class_histogramgives instance counts per class with a much smaller footprint, and two histograms already show growth.jcmd <pid> GC.heap_infoprints a short summary of the heap and its regions or generations.- JDK Flight Recorder's Old Object Sample event tracks a sample of long-lived objects and, if requested, their paths to GC roots, at low cost. See the JFR guide.
And if the heap is fine but the process is still too big, the problem is outside the heap: direct buffers, Metaspace or other native memory.
Sources
- The jcmd command (GC.heap_dump, GC.class_histogram, GC.heap_info)
- Java Platform Troubleshooting Guide: Diagnostic Tools
- The java command (HeapDumpOnOutOfMemoryError, HeapDumpPath, ExitOnOutOfMemoryError)
- Eclipse Memory Analyzer documentation
MemoryGC roots and memory leaks
What counts as a GC root, the usual accidental references, and how to walk from a suspect object back to its root.
MemoryDirect buffer memory and MaxDirectMemorySize
Why the error appears while the heap looks fine, what the default limit really is, and how to measure direct buffers.
Threads & CPUReading thread dumps
Take a series, read states and lock lines, and let the JVM point out deadlocks for you.