BackendBench
Coffee
Free tool

Java thread dump analyzer

Paste a thread dump and get deadlocks, lock owners, pool summaries and grouped stacks instead of thousands of lines.

Findings

Blocked threads

Pools

Threads with identical stacks

Find out what a Java application is doing right now

When a Spring Boot service hangs, its CPU spikes or requests pile up, a thread dump is the fastest way to see what every thread is doing at that moment. The trouble is reading it: a busy application prints thousands of lines, most of them identical Tomcat or Netty idle threads, and the interesting handful is buried in the middle.

Paste the output of jstack, jcmd Thread.print or kill -3 and the analyser parses every thread, counts them by state, groups them by pool (http-nio-8080-exec-1, -2 and so on become one pool), and groups threads with identical stacks so you see "40 threads all waiting in the same place". It matches lock owners and waiters to find deadlocks and shows who holds the lock that blocked threads are waiting for. It also flags connection-pool exhaustion (many threads waiting in HikariPool.getConnection), RUNNABLE threads that are really waiting on I/O, and busy threads executing application code.

How to use dumps well

Thread dumps contain class and method names from your code, so treat them as internal. The analysis runs entirely in your browser.

Frequently asked questions

How do I take a thread dump?

Run jstack <pid> > dump.txt (the pid comes from jps), or jcmd <pid> Thread.print, or send kill -3 <pid> to print it to the application's stdout. In Kubernetes use kubectl exec to run jcmd in the container. Take three dumps a few seconds apart.

What do the thread states mean?

RUNNABLE is executing or ready (and also native I/O waits), BLOCKED is waiting to enter a synchronized block, WAITING waits indefinitely (park, wait, join), and TIMED_WAITING waits with a timeout (sleep, timed wait). NEW and TERMINATED are rare in dumps.

Why are idle threads shown as RUNNABLE?

Java reports a thread blocked in a native socket or file read as RUNNABLE because it has not yielded through a Java-level lock. The analyser treats threads whose top frame is a known native wait (socketRead0, epollWait, read0) as probably idle.

What is a deadlock?

Two or more threads each hold a lock that another needs, so none can ever continue. They appear as BLOCKED threads whose "waiting to lock" addresses match another thread's "locked" addresses in a cycle.

More tools you might need