skip to content

JDK Diagnostic Tools

The JDK ships the tools you need to inspect a live or crashed JVM: memory, GC, threads and heap state, no external agent required. Interviewers ask which command you would run first on a misbehaving production JVM.

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

explore

questions

25

What is jcmd, and why is it considered the modern, recommended replacement for one-off tools like jmap and jstack?

level: juniorimportance: must knowfreq 70%

answer

  1. One tool, many sub-commands (Thread.print, GC.*, VM.*, JFR.*)
  2. jcmd with no args = list JVMs; jcmd <pid> help = list commands
  3. Uses the cooperative attach mechanism, same user/host
  4. Replaces jmap/jstack/jinfo (legacy, less safe)
  5. Identify target by PID or main-class name

basics

~20 s

jcmd is a JDK command-line tool that sends diagnostic commands to a running JVM. Instead of separate tools, one tool can dump the heap, print threads, run GC, show flags, and more. It's safer and unified, so it replaces jmap and jstack.

solid answer

~40 s

jcmd is a unified diagnostic command tool shipped with the JDK (in the bin directory). You point it at a running JVM by process id and issue a sub-command such as Thread.print, GC.heap_dump, GC.class_histogram, VM.flags, or JFR.start. It talks to the target over the JVM's attach mechanism, so the target must be the same user (and usually the same machine). It is the recommended replacement for the older one-purpose tools because those (jmap, jstack, jinfo) are deprecated/less maintained, each used a slightly different attach path, and some forced unsafe modes. jcmd consolidates everything behind one interface, exposes the live list of supported commands via 'jcmd <pid> help', and uses only the safe serviceability path. Running 'jcmd' with no arguments lists all attachable JVMs.

go deeper

for a junior

Knows jcmd is a CLI tool to inspect a running JVM and that 'jcmd' lists JVMs while 'jcmd <pid> help' lists commands.

for a middle

Can name the main command families (Thread.print, GC.heap_dump, VM.flags, JFR.*) and explain it replaces jmap/jstack.

for a senior

Explains the attach mechanism, same-user/same-host constraint, and why jcmd is safer and the maintained path versus the legacy one-off tools.

for a principal

Frames jcmd within a production diagnostics strategy: when to use it vs always-on JFR/agents, attach-mechanism security implications, and standardizing runbooks around it.

## What jcmd is **The JVM (Java Virtual Machine)** is the process that runs your Java program. While it runs, it holds rich internal state: the heap (where objects live), all the threads, the chosen garbage-collector settings, system properties, and more. To *inspect or influence* that state from outside, the JDK ships a family of command-line **diagnostic tools** in its `bin/` directory. Historically these were *one tool per job*: `jmap` (heap dumps, histograms), `jstack` (thread dumps), `jinfo` (flags/properties), `jstat` (GC statistics). **jcmd** is a single tool that subsumes most of them. You give it a target JVM and a *sub-command*, and it asks that JVM to perform a diagnostic action and return the result. ## How you invoke it ``` jcmd # list every JVM you can attach to (pid + main class) jcmd <pid> help # list the diagnostic commands THIS jvm supports jcmd <pid> help <command> # show the arguments for one command jcmd <pid> <command> [args] # run it ``` The target is identified by its **PID (process id)**. You can also use the main-class name instead of a numeric pid. Examples: ``` jcmd 4242 Thread.print jcmd 4242 GC.heap_dump /tmp/app.hprof jcmd MyApp VM.flags ``` ## Why it works — the attach mechanism jcmd does not read another process's memory directly. It uses the JVM **attach API / serviceability agent path**: it signals the target JVM, the target spins up an internal attach listener, and the two communicate over a local socket (a file under the temp dir on Linux/macOS). Because of this: - The target JVM must be **running** and must accept attach (it does by default unless `-XX:+DisableAttachMechanism` was set). - jcmd must run as the **same OS user** as the target (or with sufficient privilege) and normally **on the same host** — it is not a remote tool. ## Why it replaces jmap / jstack 1. **Unification.** One binary, one mental model, one help system. Discoverability is built in: `jcmd <pid> help` lists exactly what the *running* JVM supports. 2. **Safety.** The old tools could fall back to a *forced* mode that paused or even risked the target. jcmd uses only the cooperative attach path, so it is safer on production JVMs. 3. **Maintenance.** `jmap`/`jstack`/`jinfo` are effectively legacy (some marked for removal); new diagnostic capabilities (JFR control, finer GC commands, NMT) are added to jcmd, not to the old tools. 4. **No flag-juggling.** Each legacy tool had its own flags and quirks; jcmd presents a consistent `command arg=value` grammar. ## The command families you should know - **Threads:** `Thread.print` → a full thread dump (stack of every thread, lock info) — the jstack replacement. - **Heap:** `GC.heap_dump <file>` → an HPROF heap dump; `GC.class_histogram` → per-class instance counts/bytes; `GC.run` → request a full GC — the jmap replacements. - **VM introspection:** `VM.flags` (all the -XX flags in effect), `VM.system_properties`, `VM.version`, `VM.command_line`, `VM.uptime` — the jinfo replacements. - **JFR (Java Flight Recorder):** `JFR.start`, `JFR.dump`, `JFR.stop`, `JFR.check` → start/stop/collect a low-overhead profiling recording. - **NMT (Native Memory Tracking):** `VM.native_memory` (when started with `-XX:NativeMemoryTracking=summary`). ## Bottom line jcmd is the *front door* to JVM diagnostics: discover JVMs (`jcmd`), discover commands (`jcmd <pid> help`), then run them. It is preferred over the scattered legacy tools because it is unified, safer, discoverable, and where new capabilities land.

  • How do you find out which commands a specific JVM supports?
    Run 'jcmd <pid> help' to list them, and 'jcmd <pid> help <command>' to see one command's arguments. The list is the live set the running JVM actually supports.
  • Can jcmd attach to a JVM running as a different user?
    Not normally. The attach mechanism requires the same OS user (or elevated privilege) and the same host; jcmd is a local tool, not remote.

saying these in an interview costs you the question

  • Thinking jcmd is a remote/monitoring tool — it attaches locally as the same user
  • Confusing jcmd with jconsole/VisualVM (GUIs) — jcmd is CLI
  • Believing it reads the target's memory directly rather than via the attach API
  • Claiming jmap/jstack are gone today — they still exist but are legacy/deprecated

context

open as a page

What are jconsole and VisualVM, and when would you reach for each to monitor a running JVM?

level: juniorimportance: must knowfreq 60%

basics

~20 s

Both are free GUI tools that ship with (or pair with) the JDK to watch a live Java program: heap memory, garbage collection, thread count and CPU. jconsole is the minimal built-in monitor; VisualVM does more, including CPU/memory profiling and dumps.

open as a page

What is jmap, and what are its two most common uses for inspecting a running Java application's heap?

level: juniorimportance: must knowfreq 62%

basics

~20 s

jmap is a JDK command-line tool that inspects a running Java program's heap (its object memory). Its two main uses are printing a histogram of how many objects of each class exist, and dumping the whole heap to a file for offline analysis.

open as a page

What is jstack and what does it produce? When would you reach for it?

level: juniorimportance: must knowfreq 68%

basics

~20 s

jstack is a JDK command-line tool that prints a thread dump: a snapshot of every thread in a running Java process and what line of code each one is currently executing. You use it when an app hangs, is frozen, or is using too much CPU.

open as a page

How do you capture a thread dump with jcmd, and what would you look for in the output when diagnosing a hang or high CPU?

level: middleimportance: must knowfreq 68%

basics

~10 s

Run 'jcmd <pid> Thread.print' to print every thread's stack. To diagnose a hang look for BLOCKED threads and deadlocks; for high CPU look for RUNNABLE threads stuck in the same code across several dumps.

open as a page

In a jstack thread dump, what do the thread states RUNNABLE, BLOCKED, WAITING and TIMED_WAITING mean, and what does each tell you during triage?

level: middleimportance: must knowfreq 61%

basics

~20 s

RUNNABLE = the thread is running or ready to run. BLOCKED = it's stuck waiting to enter a synchronized block another thread holds. WAITING = it's parked indefinitely until notified. TIMED_WAITING = same but with a timeout (e.g. sleep). They tell you whether a thread is busy or stuck and on what.

open as a page

What is jstat, and how do you use it to monitor a running JVM's garbage collection?

level: juniorimportance: should knowfreq 35%

basics

~20 s

jstat is a command-line tool shipped with the JDK that prints live JVM statistics, mostly about memory and garbage collection. You point it at a running Java process by its PID and it can repeat at an interval, e.g. jstat -gcutil 12345 1000 prints GC stats every 1000 ms.

open as a page

Compare GC.heap_dump, GC.class_histogram, and GC.run in jcmd. When would you reach for each, and what are the production cautions?

level: middleimportance: should knowfreq 60%

basics

~20 s

GC.class_histogram lists how many instances and bytes each class uses — a quick memory overview. GC.heap_dump writes a full snapshot file you analyze in a tool to find leaks. GC.run requests a garbage collection. All can pause the app, so use them carefully in production.

open as a page

What do jcmd's VM.flags and VM.system_properties tell you, and how would you use them to debug a misconfigured production JVM?

level: middleimportance: should knowfreq 45%

basics

~20 s

VM.flags shows the JVM's -XX options actually in effect (heap size, GC, etc.). VM.system_properties shows the Java system properties (like java.version or user-set -D values). Together they let you confirm what the running JVM is really configured with versus what you intended.

open as a page

In VisualVM, what is the difference between sampling and instrumenting (profiling) CPU, and when do you use each?

level: middleimportance: should knowfreq 50%

basics

~20 s

Sampling periodically takes a snapshot of what each thread is running and adds up where time is spent — cheap but approximate. Instrumenting modifies the code to record every method call — precise but slow and it can skew the numbers.

open as a page

Explain the flags in `jmap -dump:live,format=b,file=heap.hprof <pid>`. What does each part do, and why does 'live' matter?

level: middleimportance: should knowfreq 48%

basics

~20 s

It dumps the heap to a file. live includes only reachable objects (and runs a garbage collection first), format=b writes the standard binary .hprof format, and file=heap.hprof is the output path. 'live' matters because it filters out short-lived garbage so a leak stands out.

open as a page

How does jstack help you detect and diagnose a deadlock?

level: middleimportance: should knowfreq 57%

basics

~20 s

jstack automatically finds deadlocks. When two or more threads each hold a lock the other needs, jstack prints a 'Found one Java-level deadlock' section naming the threads and which lock each holds and waits for, so you see the cycle directly.

open as a page

Walk through the columns of `jstat -gcutil` output. What does each one tell you?

level: middleimportance: should knowfreq 30%

basics

~20 s

-gcutil shows the percentage full of each memory area — S0, S1 (survivor spaces), E (eden), O (old), M (metaspace), CCS (compressed class space) — plus counts and total times of young GCs (YGC/YGCT) and full GCs (FGC/FGCT), and the overall GC time (GCT).

open as a page

How do you use jcmd to control Java Flight Recorder (JFR) on a running JVM, and why is JFR often preferred over ad-hoc heap/thread dumps for performance investigations?

level: seniorimportance: should knowfreq 52%

basics

~20 s

Use jcmd to start, check, dump, and stop a flight recording: 'JFR.start', 'JFR.check', 'JFR.dump filename=...', 'JFR.stop'. JFR records CPU, allocations, locks, and GC over time at very low overhead, so it captures continuous behavior that one-off dumps miss.

open as a page

How do you use a VisualVM heap dump to hunt a memory leak, and what does the live monitoring view show beforehand?

level: seniorimportance: should knowfreq 45%

basics

~20 s

First the live memory graph hints at a leak: used heap keeps climbing across GCs and never settles. Then you capture a heap dump — a snapshot of every object — and look for which classes hold the most memory and what chain of references keeps them alive so the garbage collector can't free them.

open as a page

How do jconsole and VisualVM connect to a JVM — local attach versus remote JMX — and what does monitoring a containerized or remote JVM require?

level: seniorimportance: should knowfreq 42%

basics

~20 s

On the same machine the tools auto-discover and attach to local Java processes with no setup. To watch a JVM on another host or in a container, you must start it with JMX remote enabled (a port, plus authentication and TLS) and connect to that address.

open as a page

When debugging a memory issue, when would you reach for `jmap -histo` versus capturing a full heap dump? What can each tell you that the other cannot?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Use -histo for a quick, cheap look at which classes have the most instances and bytes. Capture a full heap dump when you need to know why objects are kept alive — the reference chains and who is holding them — which only an analyzer working on a dump can show.

open as a page

Walk through how you'd use jstack together with top to find which Java code is burning CPU.

level: seniorimportance: should knowfreq 54%

basics

~20 s

Run top with per-thread view (top -H) to find the OS thread eating CPU and note its thread id. Convert that decimal id to hexadecimal. Take a jstack dump and search for that hex value as the nid in a thread's header — its stack trace shows the exact hot code.

open as a page

Why do you take multiple thread dumps over time, and how do you read them to diagnose stuck threads and contention?

level: seniorimportance: should knowfreq 46%

basics

~20 s

A single dump is just one instant, so you can't tell a momentarily-busy thread from a truly stuck one. Take several dumps a few seconds apart: a thread on the same stack frame in every dump is stuck, and many threads piling up on one lock across dumps reveals contention.

open as a page

An app is slow and you suspect GC. Using jstat alone, how do you confirm GC churn or a heap leak, and what are jstat's limits here?

level: seniorimportance: should knowfreq 28%

basics

~20 s

Run jstat -gcutil <pid> 1000 and watch over time. Frequent full GCs (FGC climbing) with growing FGCT and an Old region that stays high after each full GC point to GC churn or a leak. To find the actual culprit objects you still need a heap dump, because jstat only shows aggregate numbers, not what's filling the heap.

open as a page

What is the performance and safepoint impact of dumping a large heap with jmap in production, and how would you mitigate it?

level: principalimportance: should knowfreq 34%

basics

~20 s

Dumping a large heap pauses the application: the JVM must stop all threads at a safepoint to walk the object graph, and live adds a full garbage collection on top. On a multi-gigabyte heap this can mean seconds of freeze plus heavy disk and memory pressure.

open as a page

What is the MBeans browser in jconsole/VisualVM, and how would you expose and use a custom MBean for live introspection?

level: middleimportance: nice to knowfreq 30%

basics

~20 s

An MBean is a Java object that publishes data and actions for management tools. The MBeans tab in jconsole/VisualVM is a tree of all registered MBeans where you can read values and run operations live. You expose your own by defining an interface and registering it with the platform MBean server.

open as a page

Given a `jmap -histo` output sample, how do you read it and decide which class to investigate first?

level: middleimportance: nice to knowfreq 30%

basics

~20 s

Each row shows a class with how many instances exist and how many bytes they use, sorted with the biggest memory users at the top. Start by looking at the rows with the most bytes, and watch out for your own application classes rather than just generic ones like byte[] or String.

open as a page

How do `-gc`, `-gcutil`, and `-gccapacity` differ, and when would you reach for each?

level: middleimportance: nice to knowfreq 18%

basics

~20 s

-gcutil shows each region as a percentage full. -gc shows the same regions but as raw capacity and used bytes (in KB) plus GC times. -gccapacity shows the min, current, and max sizes each region is allowed to be. Use -gcutil for a quick health check, -gc for exact numbers, -gccapacity to see sizing limits.

open as a page

Where does jstat fit among JVM diagnostic tools, and what are its constraints for production monitoring?

level: principalimportance: nice to knowfreq 16%

basics

~20 s

jstat is a quick, low-overhead, command-line way to watch live GC and memory counters for one JVM. It's great for ad-hoc triage but it only shows aggregate numbers, samples one process interactively, and isn't a real monitoring system. For production fleets you use GC logs, JFR, and a metrics pipeline (e.g. Prometheus) instead.

open as a page