Java (JVM) Debugging Tools
Luke Hebert
- 2 minutes read - 412 wordsWhen a Java application starts misbehaving, you need visibility into what the JVM is doing without restarting the process. The tools below let you inspect the heap, read the runtime environment, and turn on garbage collection logging on a live process. All of them work against a running JVM identified by its process ID (PID).
Map the Java Heap
The jmap utility gives you a snapshot of the heap layout. Use it to see object counts, memory usage per generation, and to generate heap dumps for offline analysis.
jmap -heap <pid>This prints a summary of the heap configuration, current usage, and the garbage collector in use. If you need a full heap dump for tools like Eclipse MAT or VisualVM, add the -dump flag:
jmap -dump:format=b,file=heap.hprof <pid>Get Environment Information for the JVM
Sometimes the issue is not the code but the environment the JVM was started in. Two approaches work well:
<java home>/bin/jinfo <pid>jinfo prints the system properties, VM flags, and classpath that the running process is using. It is the closest thing to a “what did the JVM actually start with?” command.
As a cross-check, you can read the raw environment variables the process inherited:
cat /proc/<pid>/environ | tr '\0' '\n'This is especially handy on Linux when you suspect a JAVA_OPTS or LD_LIBRARY_PATH issue.
Enable GC Debugging
If you suspect memory pressure or long pauses, turn on GC logging on the running process. Each flag below can be toggled live with jinfo:
jinfo -flag +PrintGC <pid>
jinfo -flag +PrintGCDetails <pid>
jinfo -flag +PrintGCTimeStamps <pid>
jinfo -flag +HeapDumpOnOutOfMemoryError <pid>- PrintGC - logs every collection event.
- PrintGCDetails - adds per-generation sizes and object counts.
- PrintGCTimeStamps - prepends a timestamp to each GC log line.
- HeapDumpOnOutOfMemoryError - writes a
.hproffile automatically if the JVM hits anOutOfMemoryError, so you do not lose the evidence.
On JDK 9 and later, the PrintGC* flags are deprecated in favor of the unified logging system. Use -Xlog:gc* at startup instead. The jinfo commands above still work on JDK 8, which is still common in enterprise environments.
Quick Reference
| Task | Command |
|---|---|
| Heap summary | jmap -heap <pid> |
| Heap dump | jmap -dump:format=b,file=heap.hprof <pid> |
| JVM flags and properties | jinfo <pid> |
| Process environment | cat /proc/<pid>/environ |
| Enable GC logging | jinfo -flag +PrintGC <pid> |
| Auto-dump on OOM | jinfo -flag +HeapDumpOnOutOfMemoryError <pid> |
Keep these in your runbook. They save a lot of guesswork when a Java service starts eating memory or throwing OutOfMemoryError in production.