Find the process
systemctl show -p MainPID --value myapp # PID of a systemd service
pgrep -af java # all Java processes
The JDK tools must run as the same user as the JVM, and with a JDK, not a JRE. Use sudo -u appuser. They are in the openjdk-21-jdk-headless package.
Thread dump
A thread dump shows what every thread is doing right now. Take three, ten seconds apart, so you can see what is stuck and what only looks busy.
for i in 1 2 3; do sudo -u appuser jcmd <pid> Thread.print -l > /tmp/threads-$i.txt; sleep 10; done
If jcmd cannot attach, sudo kill -3 <pid> prints the dump into the application's standard output (the journal or catalina.out). It does not stop the process.
Reading it
- Same stack in all three dumps for many threads, often waiting for a lock or a database connection: look for
BLOCKEDorWAITINGand the linewaiting to lock <0x...>, then find which thread holds that lock. - Many threads at
getConnectionin the pool: the connection pool is exhausted, either connections are leaked or queries are slow. - High CPU: find the hot thread. Run
top -H -p <pid>, take the thread ID with the highest CPU, convert it to hex (printf '%x\n' TID) and search the dump fornid=0x.... Found one Java-level deadlockat the bottom: jcmd prints it for you.
Upload the dumps to a thread dump analyzer, or read them yourself with grep. Remove customer data before sharing a dump publicly: stacks can include request details.
Heap dump
sudo -u appuser jcmd <pid> GC.heap_dump /var/tmp/heap.hprof
ls -lh /var/tmp/heap.hprof
The file is about the size of the live heap, and taking it pauses the application while it writes. Check df -h first. Compress and copy it off the server:
gzip /var/tmp/heap.hprof
scp deploy@server:/var/tmp/heap.hprof.gz .
Open it in Eclipse Memory Analyzer on your computer. Then delete it from the server, because a heap dump contains passwords, tokens and personal data in plain text. Handle it like a database backup. To get a dump automatically at the moment of failure, use -XX:+HeapDumpOnOutOfMemoryError, see fix OutOfMemoryError.
Other quick checks
sudo -u appuser jcmd <pid> GC.heap_info
sudo -u appuser jcmd <pid> VM.flags
sudo -u appuser jstat -gcutil <pid> 2s 10
These show the current heap use, the effective JVM flags and GC activity, without stopping anything.
Last updated October 29, 2026.