This process—choosing the blocking event from the histogram and examining the calling
code—works for any kind of blocking event; it is made possible by the tight integration of
the tool with the JVM.
Blocked threads and JStack
If a commercial version of the JVM is not available, one alternative is to take a lot of thread
stacks from the program and examine those. jstack , jcmd , and other tools can provide in-
formation about the state of every thread in a VM, including whether the thread is running,
waiting for a lock, waiting for I/O, and so on. This can be quite useful for determining what's
going on in an application, as long as too much is not expected from the output.
The first caveat in looking at thread stacks is that the JVM can only dump a thread's stack at
certain locations (safepoints). Second, stacks are dumped for each thread one at a time, so it
is possible to get conflicting information from them: two threads can show up holding the
same lock, or a thread can show up waiting for a lock that no other thread holds.
A JSTACK PROFILER
It is tempting to think you can take multiple stack dumps in rapid succession and use that data as
a quick-and-dirty profiler. After all, sampling profilers work in essentially the same way: they
periodically probe the stack a thread is executing and extrapolate how much time is spent in meth-
ods based on that. But between safepoints and inconsistent snapshots, this doesn't work out too
well; you can sometimes get a very high-level overview of the expensive methods in your applic-
ation by looking at thread stacks, but a real profiler will give far more accurate information.
Thread stacks can show how significantly threads are blocked (since a thread that is blocked
is already at a safepoint). If successive thread dumps show a large number of threads blocked
on a lock, then you can conclude that the lock in question has significant contention. If suc-
cessive thread dumps show a large number of threads blocked waiting for I/O, then you can
conclude that whatever I/O they are reading needs to be tuned (e.g., if they are making a
database call, the SQL they are executing needs to be tuned, or the database itself needs to be
The online examples for this topic have a rudimentary parser for jstack output that can
summarize the state of all threads from one or more thread dumps. A problem with jstack
output is that it can change from release to release, so developing a robust parser can be diffi-