skip to content

Heap Dumps & Profiling Tools

The practical toolchain for memory problems: capture a heap dump with jmap or HeapDumpOnOutOfMemoryError, then read dominator trees and retained sizes in MAT or VisualVM, with JFR, async-profiler and jstat for live observation. Interviewers ask how you would actually chase a leak in production, and this is the answer.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What is a heap dump, and what are the main ways to capture one from a running or crashing JVM?

level: juniorimportance: must knowfreq 62%

answer

  1. Snapshot of every object on the heap → .hprof file
  2. jmap -dump:live + -XX:+HeapDumpOnOutOfMemoryError + jcmd GC.heap_dump
  3. OOM auto-dump = captures the moment of failure
  4. Capturing pauses the app; file ~ heap size
  5. Snapshot, not a trend

basics

~20 s

A heap dump is a snapshot of all objects in the JVM heap at one moment, saved to a file. You can trigger it on demand with jmap, or have the JVM write one automatically when it runs out of memory using the -XX:+HeapDumpOnOutOfMemoryError flag.

solid answer

~40 s

A heap dump is a binary snapshot (HPROF format, usually a .hprof file) of every live and dead object on the Java heap at the instant it is taken, including each object's class, fields, and references to other objects. It lets you analyze what is occupying memory after the fact. The common capture methods are: on demand with jmap -dump:live,format=b,file=heap.hprof <pid>; automatically on an OutOfMemoryError by launching with -XX:+HeapDumpOnOutOfMemoryError (optionally -XX:HeapDumpPath=...); via jcmd <pid> GC.heap_dump file.hprof; or through a profiler like VisualVM or a JMX/management agent. The dump can be large (gigabytes) and capturing it pauses the application, so it is usually a diagnostic step, not a routine one.

go deeper

for a junior

Knows a heap dump is a snapshot of heap objects, and that jmap or the OOM flag produces one. Can name the .hprof file.

for a middle

Can choose the right capture method per situation, knows live-vs-all dump, the stop-the-world cost, and that the file is roughly heap-sized.

for a senior

Sets -XX:+HeapDumpOnOutOfMemoryError with a HeapDumpPath in production, manages disk/secrets concerns, and prefers jcmd over the older jmap.

for a principal

Defines the org-wide policy for dump capture (where dumps land, retention, redaction of sensitive data, automated triggers) and weighs the pause cost against the diagnostic value on a per-service basis.

## What is the heap? In Java, objects you create with `new` live in a region of memory called the **heap**, which is managed by the **garbage collector (GC)** — the JVM subsystem that automatically frees objects no longer reachable. The heap is shared across all threads. (Local variables and method call frames live on per-thread **stacks**, which are separate.) ## What is a heap dump? A **heap dump** is a complete snapshot of the heap at a single moment: a file listing every object instance, its class, the values of its fields (primitives and references), and which other objects each one points to. Think of it as a freeze-frame photograph of the entire object graph. The standard on-disk format is **HPROF**, a binary format, typically saved with a `.hprof` extension. A heap dump answers the question: *what is in memory right now, and why is it being kept alive?* That makes it the primary tool for diagnosing high memory use and memory leaks (objects that stay reachable but are never used again). ## How to capture one There are four common ways, each useful in a different situation: 1. **On demand with `jmap`** (ships with the JDK). You need the target process id (`pid`), which `jps` lists: ``` jmap -dump:live,format=b,file=heap.hprof <pid> ``` The `live` option triggers a full GC first so the dump contains only reachable objects (smaller, cleaner). Omit `live` to capture *everything*, including garbage not yet collected. 2. **Automatically on OutOfMemoryError.** Add JVM flags at startup: ``` -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/dumps ``` When the JVM throws `OutOfMemoryError`, it writes a dump just before dying. This is the most valuable setting for production: the dump captures the heap *at the moment of failure*, which you can rarely reproduce later. It is cheap when nothing fails (it only fires on OOM). 3. **With `jcmd`** (the modern, preferred diagnostic command): ``` jcmd <pid> GC.heap_dump /path/heap.hprof ``` `jcmd` is the umbrella tool that has largely superseded `jmap`. 4. **Through a profiler / GUI**: VisualVM, JDK Mission Control, or an IDE can attach to a live JVM and request a dump with a button. ## Important practical points - **Capturing a dump pauses the application** (a stop-the-world pause) while the heap is walked. On a multi-gigabyte heap this can take seconds to minutes, so you don't do it casually on a latency-sensitive production node. - **The file is roughly the size of the live heap** — a 4 GB heap produces a multi-GB file. Make sure the disk has room (especially for the automatic OOM dump path). - A heap dump is a **point-in-time snapshot**, not a recording over time. To watch memory *trend*, you use live monitoring tools (jstat, JFR) instead, and reach for a dump when you need to see object-level detail. - The dump contains **application data** (strings, user records, possibly secrets), so treat dump files as sensitive.

  • Why might you prefer -XX:+HeapDumpOnOutOfMemoryError over manually running jmap?
    Because the automatic dump captures the heap at the exact instant of failure, which is usually impossible to reproduce by hand later. By the time you notice the OOM and run jmap, the process may already be dead or in a different state.
  • What is the difference between a heap dump and a thread dump?
    A heap dump captures objects on the heap (memory contents). A thread dump captures the stack traces and states of all threads (what code each thread is running) — used for diagnosing hangs, deadlocks, and CPU issues, not memory.

saying these in an interview costs you the question

  • Thinking a heap dump records memory usage over time — it is a single snapshot, not a recording.
  • Believing the dump is free/instant — it triggers a stop-the-world pause and can be gigabytes.
  • Confusing a heap dump (objects on the heap) with a thread dump (stack traces of threads).
  • Assuming -XX:+HeapDumpOnOutOfMemoryError dumps continuously; it only fires on an actual OutOfMemoryError.

context

open as a page

When analyzing a heap dump, what is the difference between shallow size and retained size, and how does a dominator tree help you find a leak?

level: seniorimportance: must knowfreq 58%

basics

~20 s

Shallow size is the memory one object uses by itself. Retained size is all the memory that would be freed if that object were removed — the object plus everything only it keeps alive. A dominator tree shows which objects hold the most memory, so you look at the biggest retained sizes to find the leak.

open as a page

Name the JDK's live JVM monitoring and profiling tools and say what each is best at: jstat, VisualVM, Java Flight Recorder, and async-profiler.

level: middleimportance: should knowfreq 50%

basics

~20 s

jstat prints live GC and memory stats from the command line. VisualVM is a GUI that shows memory, threads, and lets you take dumps. Java Flight Recorder records detailed events with very low overhead for later analysis. async-profiler is a low-overhead sampling profiler great for CPU and allocation flame graphs.

open as a page

Walk through how you would diagnose a slow memory leak in a long-running production Java service, from first symptom to root cause.

level: seniorimportance: should knowfreq 46%

basics

~20 s

Confirm the leak by watching memory climb over time and never fully recover after GC. Enable an automatic heap dump on OutOfMemoryError, or take dumps at intervals and compare. Open the dump in a tool like Eclipse MAT, sort by retained size, find the object retaining the most, and trace its path to GC roots to see what code keeps it alive.

open as a page

Heap dumps pause the JVM and can be gigabytes. How do you design a production memory-diagnostics strategy that gets you actionable data without destabilizing the service?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

Rely on always-on low-overhead tools like Java Flight Recorder and GC logs for continuous insight, and reserve full heap dumps for when you really need object-level detail. When you must dump, do it on one instance taken out of rotation, write to fast local disk, and have a plan for where dumps go and how sensitive data in them is protected.

open as a page