Thread dump
Preferred since JDK 9: jcmd. It uses the attach API the same way jstack does
but ships with every JDK and works for many other diagnostics too.
jcmd ${{ PID }} Thread.print > thread_dump.txtjstack still works and is fine as a fallback (it is not formally deprecated,
but jcmd is the modern recommendation):
jstack ${{ PID }} > thread_dump.txtIf neither tool is on PATH, use the one from the same JDK as the running
process — an attach-API tool must be the same version as the target JVM or newer,
never older:
$JAVA_HOME/bin/jcmd ${{ PID }} Thread.print > thread_dump.txtOr send QUIT (signal 3) to the JVM and the dump is written to the process’s
own stdout:
kill -3 ${{ PID }}Containers
Section titled “Containers”jcmd / jstack need to see the target process in the same PID namespace
and need access to the attach socket under /tmp/.java_pid<pid>. Easiest path:
run the tool inside the container:
docker exec -it <container> jcmd 1 Thread.print(PID 1 inside the container is usually the JVM.) Alternatively run it from a
sidecar that shares pid and a writable /tmp with the JVM container.
kill -3 always works from inside, but the dump goes to the container’s stdout —
so it lands wherever PID 1’s stdout goes. If the entrypoint pipes the JVM through a
shell wrapper, a log shipper, or tee, that pipe is block-buffered and the dump can
sit there unflushed. Confirm it actually reaches docker logs / your aggregator before
you rely on this in an incident; jcmd ... Thread.print > file avoids the problem
entirely.