← Back to list

jcmd: The Swiss Army Knife of JVM Diagnostics (Or How to Stop Wondering What Your Java App is…

The Not-So-Secret Weapon That’s Been Hiding in Your JDK Bin Folder All Along

Vivek D · 2025-09-22 15:52 · 6 claps · 4.5 min read paywalled
#java #jcmd #jvm #programming #software-development
Open on Medium ↗
Wiki topics: CLI · Clinical Medicine 💻 · Programming

jcmd: The Swiss Army Knife of JVM Diagnostics (Or How to Stop Wondering What Your Java App is Actually Doing)

The Not-So-Secret Weapon That’s Been Hiding in Your JDK Bin Folder All Along

If you’re not a member, click here to read free.

Remember when troubleshooting Java applications meant running seven different tools, opening three monitoring applications, and sacrificing a goat to the JVM gods? Those days are thankfully behind us, thanks to jcmd - the diagnostic tool that decided to be the overachiever in the JDK toolbox.

Think of jcmd as that friend who knows a little bit about everything and can help you fix your car, debug your code, and probably cook a decent meal too. It's the command-line utility that consolidated the functionality of multiple older tools like jstack, jmap, jinfo, and others into one gloriously efficient package.

What Exactly is jcmd?

The jcmd tool is a diagnostic command utility that sends diagnostic command requests to running Java Virtual Machine processes. It's like having a direct hotline to your JVM, allowing you to poke, prod, and interrogate your running Java applications without the need for additional setup or configuration.

The beauty of jcmd lies in its simplicity - it uses the same machine and user credentials as your running JVM, which means no complex authentication or remote connection setup required. It's the lazy developer's dream tool, and I mean that in the best possible way.

Getting Started: The Basics That Actually Matter

Finding Your Java Processes

First things first, you need to find your Java processes. Running jcmd without any arguments (or with -l) lists all running Java processes:

jcmd
# or
jcmd -l

This gives you output like:

23876 sun.tools.jcmd.JCmd
32311 MyAwesomeApplication

Notice how jcmd includes itself in the list? That's because it's also a Java application. Meta, isn't it?

Discovering Available Commands

Once you have your process ID, you can discover what diagnostic commands are available:

jcmd <PID> help

This returns a comprehensive list of available commands, which might include:

  • JFR commands: JFR.start, JFR.stop, JFR.dump, JFR.check
  • GC commands: GC.heap_dump, GC.run, GC.class_histogram
  • Thread commands: Thread.print
  • VM commands: VM.flags, VM.system_properties, VM.uptime

The Heavy Hitters: Commands That Actually Save Your Day

Thread Dumps: When Your App Decides to Take a Nap

Thread dumps are your best friend when your application suddenly decides that responding to requests is overrated. The Thread.print command gives you a complete snapshot of all threads:

jcmd <PID> Thread.print

This command provides detailed information about each thread including its state, stack trace, and any locks it’s holding. It’s particularly useful for identifying deadlocks, performance bottlenecks, and threads that are stuck in infinite loops (we’ve all been there).

You can also save the output to a file for later analysis:

jcmd <PID> Thread.print > my_thread_dump.txt

Heap Dumps: Memory Detective Work Made Easy

When your application starts eating memory like it’s going out of style, heap dumps become invaluable. The GC.heap_dump command creates a snapshot of your heap:

jcmd <PID> GC.heap_dump /path/to/my_heap_dump.hprof

Pro tip: Always use absolute paths! Relative paths are interpreted from the JVM’s working directory, not your current directory. Trust me, you don’t want to spend 20 minutes hunting for a heap dump file.

For Java 11 and above, you can even compress the heap dump:

jcmd <PID> GC.heap_dump -gz /path/to/compressed_dump.hprof

The -gz option can save significant disk space and I/O time, especially with large heap dumps.

Flight Recorder: The Black Box for Your JVM

Java Flight Recorder (JFR) is like having a flight data recorder for your JVM. Starting a recording is straightforward:

jcmd <PID> JFR.start duration=60s filename=my_recording.jfr

You can also start continuous recordings with size and time limits:

jcmd <PID> JFR.start name=continuous_recording maxage=4h maxsize=400MB

To check the status of your recordings:

jcmd <PID> JFR.check

And to dump ongoing recordings without stopping them:

jcmd <PID> JFR.dump filename=snapshot.jfr

System Information: Know Your JVM

Sometimes you just need to know what flags your JVM is running with or what system properties are set:

# View VM flags
jcmd <PID> VM.flags

# View system properties  
jcmd <PID> VM.system_properties

# View command line arguments
jcmd <PID> VM.command_line

# Check JVM uptime
jcmd <PID> VM.uptime

Garbage Collection Commands

Force garbage collection (though you probably shouldn’t in production):

jcmd <PID> GC.run

Get class histogram to see which objects are consuming memory:

jcmd <PID> GC.class_histogram

Advanced Use Cases: When Things Get Interesting

Performance Counter Analysis

jcmd can print performance counters that provide low-level JVM metrics:

jcmd <PID> PerfCounter.print

These counters give you access to internal JVM statistics that aren’t available through standard monitoring APIs. It’s like having x-ray vision into your JVM’s internal operations.

Batch Command Execution

You can execute multiple commands from a file using the -f option:

jcmd <PID> -f commands.txt

Where commands.txt contains one command per line:

Thread.print
GC.class_histogram  
VM.flags

Working with Multiple JVMs

Send commands to all Java processes by using 0 as the process ID:

jcmd 0 VM.uptime

Or target processes by main class name instead of PID:

jcmd MyApplication GC.heap_dump /tmp/heap.hprof

Real-World Scenarios: When jcmd Saves the Day

Scenario 1: High CPU Usage Investigation

When your application is consuming excessive CPU:

  1. Take multiple thread dumps spaced apart:
jcmd <PID> Thread.print > thread_dump_1.txt
sleep 10
jcmd <PID> Thread.print > thread_dump_2.txt
  1. Compare the dumps to identify hot threads

  2. Use GC.class_histogram to check for excessive object creation

Scenario 2: Memory Leak Detective Work

For suspected memory leaks:

  1. Start a continuous JFR recording:
jcmd <PID> JFR.start settings=profile duration=30m filename=memory_analysis.jfr
  1. Take heap dumps at intervals:
jcmd <PID> GC.heap_dump heap_before.hprof
# Run your application for a while
jcmd <PID> GC.heap_dump heap_after.hprof

Scenario 3: Production Troubleshooting

When you can’t restart the application:

  1. Check system properties and VM flags:
jcmd <PID> VM.system_properties | grep -i memory
jcmd <PID> VM.flags | grep -i heap
  1. Enable JMX without restart:
jcmd <PID> ManagementAgent.start_local

Why jcmd Should Be Your Go-To Tool

The real beauty of jcmd lies in its consolidation of functionality. Instead of remembering the syntax for jstack, jmap, jinfo, and other tools, you have one consistent interface. It's like having a universal remote for your JVM diagnostics.

Moreover, jcmd is actively maintained and receives new features with each JDK release, while some of the older individual tools are being deprecated or removed. Future-proofing your diagnostic scripts has never been easier.

Whether you’re debugging a production issue at 2 AM (we’ve all been there), optimizing memory usage, or just trying to understand what your application is actually doing, jcmd provides the insights you need without the complexity of external tools or additional setup.

So the next time your Java application starts acting like a moody teenager — consuming resources inexplicably, responding slowly, or just generally misbehaving — remember that jcmd is sitting right there in your JDK bin folder, ready to help you figure out what's going wrong. And unlike that moody teenager, it actually gives you useful, detailed answers.


메타데이터
post_id
189d9cefa78e
slug
jcmd-the-swiss-army-knife-of-jvm-diagnostics-or-how-to-stop-wondering-what-your-java-app-is-189d9cefa78e
url
https://medium.com/@knpqvvzrb/jcmd-the-swiss-army-knife-of-jvm-diagnostics-or-how-to-stop-wondering-what-your-java-app-is-189d9cefa78e
canonical_url
https://medium.com/@knpqvvzrb/jcmd-the-swiss-army-knife-of-jvm-diagnostics-or-how-to-stop-wondering-what-your-java-app-is-189d9cefa78e
author_url
https://medium.com/@knpqvvzrb
status
ok
fetched_at
2026-06-17 15:37:45