Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A Java thread dump is a point-in-time record of the threads in a running JVM, including their states and stack traces. To investigate a hang or slowdown, capture dumps while the symptom is happening, compare repeated snapshots, and trace blocked threads to the locks and code locations involved. A single state label—or one snapshot by itself—rarely proves the cause.

What a Java thread dump shows

A thread dump records what the JVM’s threads are doing at the moment of capture. It typically includes thread names, thread states, and stack traces: the sequence of method calls leading to each thread’s current position. Depending on the command and JVM, output can also include lock information and extended thread details.

This makes a dump useful when an application appears hung, requests stall, or many threads seem to be waiting. It is evidence about a moment, not a recording of everything that happened before or after it. A thread may move immediately after the dump is taken, so interpret the output against the timing and symptoms of the incident.

How to capture a thread dump with jcmd

Oracle documents jcmd as a utility for sending diagnostic commands to a running JVM. Run it on the same machine as the target JVM, using the same effective user and group identifiers that launched that JVM. The available diagnostic commands can depend on the JVM, so check the target process’s help rather than assuming every option is supported.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Identify the target JVM process ID (pid) using the process-identification method available on that machine.

  2. Ask that JVM which options its Thread.print command supports: jcmd <pid> help Thread.print.

  3. Capture a basic thread dump: jcmd <pid> Thread.print.

  4. If the target JVM documents support for it, include -l to print java.util.concurrent locks: jcmd <pid> Thread.print -l. Oracle’s Java 21 diagnostic guide also documents -e for extended thread information; confirm the target JVM accepts it before relying on that option.

  5. Save each output separately and note when it was captured and what users or monitoring systems were observing. This makes it possible to compare snapshots against the symptom.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If jcmd cannot attach, first check that the PID identifies the intended JVM, that the command is running on the same machine, that the effective user and group match those of the JVM, and that the target JVM supports the requested diagnostic command. An attach failure is not, by itself, evidence that the application has failed.

How to analyze a dump

Start with the symptom and the capture time

Establish what was wrong when the dump was taken: for example, whether requests were timing out or a background task had stopped progressing. A dump captured outside the affected interval may show normal operation rather than the cause. If possible, take more than one snapshot during the same incident and compare the corresponding threads and stacks.

Group threads by name and inspect their stacks

Look for groups of similarly named threads, then inspect their states and stack frames together. Thread names can help distinguish related workers, but the stack is what shows where a thread was when captured. Compare repeated snapshots: threads that remain in the same wait or lock pattern may indicate a persistent bottleneck; changing stacks may indicate movement. Neither pattern alone proves a root cause.

Pay attention to application frames as well as runtime or library frames. If several affected threads converge on the same application location, that is a useful lead to investigate. Check what those threads are waiting for and, when lock information is present, which thread owns the lock. A stack trace identifies where the thread was observed; it does not independently establish why the application reached that state.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Interpret state labels in context

Oracle’s Java troubleshooting documentation describes these thread states:

A collection of threads in WAITING does not establish that the application is hung. A worker may be waiting normally for work. For an apparent pool stall, check whether threads repeatedly appear in the same locations, whether a lock owner is making progress, and whether the observed pattern matches the time of the incident. Treat each state as a clue to follow through the stack and lock data, not as a diagnosis.

How to recognize deadlock and contention

Look for a lock-wait cycle

A deadlock involves a cycle: one thread waits for a lock held by another thread, which in turn waits for a lock held by the first or another thread in the cycle. To assess a suspected deadlock, connect the waiting thread to the lock it needs, identify the owner, and follow that owner’s own lock wait. A chain that does not form a cycle is not enough to establish deadlock.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Oracle documents deadlock detection in the Control+Break handler, whose output can identify threads, locks, and owners. JConsole’s Threading MBean also offers monitor-deadlock detection; its thread information can include stack traces and monitor lock ownership. These are additional ways to investigate lock relationships, not substitutes for matching the findings to the incident.

Separate contention from a deadlock

Contention can make threads wait on a shared lock even when the owner is still making progress. Compare snapshots to see whether the same threads keep converging on the same lock or application frames, and check whether the owner’s stack changes. A lock that appears in one snapshot may be transient; persistence across snapshots is a stronger reason to investigate, but still does not prove why the bottleneck exists.

Thread dumps also provide only capture-time evidence. They cannot show a complete timeline of lock acquisition, explain every event between captures, or establish by themselves how long a thread has been waiting. Use the application symptom, repeated snapshots, and relevant code paths together when forming a diagnosis.

When a thread dump is not enough: use JFR and JMC

A thread dump is a snapshot. If an issue is intermittent, requires a timeline, or is not explained by a few snapshots, Java Flight Recorder (JFR) can provide complementary runtime profiling and event data, including thread samples and lock profiles. Oracle describes JFR as a profiling and event collection framework built into the JDK and notes its use in production environments with very small performance overhead; that characterization is not a guarantee of zero impact.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

JDK Mission Control (JMC) visualizes JFR recordings and provides diagnostic tables, charts, and automated analysis. A recording and a plain thread dump are different diagnostic artifacts: use a dump to inspect thread states and stacks at a particular moment, and consider JFR/JMC when the missing information is how behavior unfolded over time.

Oracle documents jcmd commands for starting, checking, stopping, and dumping Flight Recorder sessions. To discover what the target JVM supports, consult its command help and release documentation; exact options can vary. Do not assume that a command or option documented for one Java release or JVM is available on another.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common thread-dump troubleshooting mistakes

Or skip the browser setup

Thread dumps diagnose Java processes; they do not capture website screenshots. For a separate website-capture task, ScreenshotNeo is a screenshot API and MCP server for developers. It removes cookie and consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, failed loads, and cache hits are not billed. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Every feature is on every plan.

For example, this cURL request captures a page as WebP; replace the URL as needed. See the ScreenshotNeo documentation for API options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Sign up free for 1,000 screenshots a month, with no card required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.