Why not paste it into an AI chatbot?
A thread dump looks harmless, but one from production is a map of your system:
- Every package and class on every stack: how your code is built and what your services are called.
- Your libraries and their versions, which tells a reader which known vulnerabilities to try.
- Thread names that carry data: client addresses (
RMI TCP Connection(2)-10.2.0.14), and tenant names, queue names or request IDs if your code names threads after them.
A chatbot sends all of it to another company's servers, where it may be kept, depending on the plan and its settings. Many companies' rules forbid pasting production data or internal code into one.
This page reads the dump in your browser and sends it nowhere. Check it yourself: open your browser's developer tools, go to the Network tab, and paste a dump. No request goes out.
It is also repeatable: the same dump always gives the same answer, from rules tested against real dumps. A chatbot reading hundreds of threads can skip some, or name a lock owner that isn't in the dump.
Use both: find the stuck threads here, then ask about the one stack frame in your own code, not the whole dump.
What it finds
- Deadlocks, on
synchronizedand onReentrantLock. - Lock contention: threads
BLOCKEDon a lock, and the thread that holds it. - Common pool starvation: every
ForkJoinPool.commonPoolworker busy while another thread waits for a result. - A full queue: producers stuck in
put(). - Threads waiting in
Future.get(),CountDownLatch.await(),Semaphore.acquire()orObject.wait(), and idle pool threads.
How to take a thread dump
jstack -l <pid>orjcmd <pid> Thread.print -l. Find the pid withjcmdorjps.-ladds "Locked ownable synchronizers", which shows who holds eachReentrantLock. Without it, onlysynchronizedowners are known.kill -3 <pid>prints a dump to the app's standard output (Linux and macOS).- Take two or three dumps a few seconds apart. A thread stuck in the same place in all of them is really stuck.
jstacklists platform threads only. Virtual threads needjcmd <pid> Thread.dump_to_file, which this page doesn't read yet.
How we know it reads dumps right
A Java program puts a JVM into known situations (deadlocks on monitors and on ReentrantLock, a contended lock, a full common pool, a latch, a full queue) and dumps itself. Tests check this page's reading of those real dumps from JDK 8, 17, 21 and 27, and CI captures fresh ones every week.
Common questions
How do I analyze a Java thread dump?
Paste the output of jstack -l <pid> or jcmd <pid> Thread.print -l into the box above. The page says what each thread is doing in plain words, who holds each lock, and what looks wrong, with a link to an animation of the same problem.
How do I find a deadlock in a thread dump?
Look for "Found one Java-level deadlock" near the end: the JVM reports deadlocks on synchronized and on ReentrantLock itself. This page shows that report first, and looks for a cycle of threads waiting on each other's locks when the paste is cut off.
What does BLOCKED mean in a thread dump?
The thread is waiting to enter a synchronized block that another thread holds. Its "waiting to lock" line names the lock, and the thread whose "locked" line shows the same address holds it.
Is it safe to paste a thread dump into ChatGPT or another AI chatbot?
Think twice with a production dump. Its class names, library versions and thread names describe your system, and a chatbot sends them to another company's servers. This page reads the dump in your browser instead: nothing is uploaded.