jcmd - send diagnostic command requests to a running Java Virtual Machine
jcmd [pid | main-class] command... | PerfCounter.print | -f filename
jcmd [-l]
jcmd -h
Options you will use
-l- List the Java processes this user can see (hsperfdata is per user).
pid- Target JVM. Use 0 for all of them.
main-class- Match JVMs whose main class or jar contains this string, e.g.
jcmd orders.jar GC.heap_info. help [command]- List the diagnostic commands the target supports, or describe one.
-f FILE- Read the diagnostic commands from FILE.
-J<flag>- Pass a flag to the JVM that runs jcmd itself.
GC.heap_info- Heap summary: size, used and capacity of each generation/region.
GC.class_histogram- Objects per class: count and bytes, biggest first. Like jmap -histo, and it forces a full GC (-all to skip it).
GC.heap_dump- Write an HPROF heap dump to the given file (a path on the TARGET's filesystem). Pauses the JVM while it writes.
GC.run- Run System.gc().
VM.flags- The VM flags in effect (-all for every flag with its value).
VM.command_line- The full JVM command line and the arguments it was started with.
VM.system_properties- All the Java system properties.
VM.native_memory- Native Memory Tracking report: summary, detail, baseline, summary.diff. Needs -XX:NativeMemoryTracking=summary at start.
VM.set_flag- Change a MANAGEABLE flag at runtime, e.g.
VM.set_flag HeapDumpOnOutOfMemoryError true. VM.uptime- How long the JVM has been running.
VM.version- The JVM version.
VM.info- Everything about the VM: flags, memory, threads, environment (like an hs_err file).
Thread.print- Print every thread's stack trace with its state (the same as jstack). -l adds the locks held.
JFR.start- Start a Java Flight Recorder recording (duration=60s filename=rec.jfr).
JFR.dump- Write the data of a running recording to a file.
JFR.stop- Stop a recording.
JFR.check- List the running recordings.
PerfCounter.print- Print the JVM's performance counters.
summary- VM.native_memory: memory per category (Java Heap, Class, Thread, Code, GC...), reserved and committed.
baseline- VM.native_memory: remember the current numbers to compare against later.
summary.diff- VM.native_memory: the change per category since the baseline - how you find a native leak.
detail- VM.native_memory: per memory region.
help- List the diagnostic commands this JVM supports (
jcmd PID help CMDdescribes one).
Examples
$ sudo -u appuser jcmd 1210 VM.flagsAttach as the JVM's own user. Another non-root user gets java.io.IOException: Operation not permitted.
$ jcmd 1210 GC.heap_infoHeap regions, used vs committed, metaspace.
$ jcmd 1210 Thread.print -lThread dump with java.util.concurrent locks.
$ jcmd 1210 GC.class_histogram | head -20Live object histogram (forces a full GC).
$ jcmd 1210 GC.heap_dump /tmp/heap.hprofThe path is resolved by the TARGET JVM, relative to ITS working directory, written as ITS user.
$ jcmd 1210 VM.native_memory summaryNeeds -XX:NativeMemoryTracking=summary at JVM start.
$ jcmd 1210 VM.native_memory baseline... then later summary.diff shows what grew.
$ jcmd 1210 JFR.start duration=60s filename=/tmp/rec.jfrFlight recording.
Gotchas
- jcmd ships with the JDK, not the JRE:
sudo apt install openjdk-21-jdk-headless. Container images built on a JRE or distroless base have no jcmd at all. - Attach works for the same user or root. The usual form on a server is
sudo -u <jvm user> jcmd <pid> ....
Taught in
Try jcmd in a real terminal Free, in your browser - a real Ubuntu terminal to try it in, with missions that check your work.