jstack 格式更改

jstack Format Change

我们一直在使用 jstack 从我们的 JVM 输出线程转储,多年来我们一直在使用 IBM Thread Analyzer 来分析线程和监视器。下面是分析器解析的 jstack (jstack -l PID > jstack.out) 输出示例。

Wed Oct  5 00:28:56 EDT 2016
2016-10-05 00:29:04
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.55-b03 mixed mode):

"Attach Listener" daemon prio=10 tid=0x00000000131e3800 nid=0x7654 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None

"Keep-Alive-Timer" daemon prio=10 tid=0x00002ad5b81c1000 nid=0x717f waiting on condition [0x00002ad5d3d7e000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at sun.net.www.http.KeepAliveCache.run(KeepAliveCache.java:172)
    at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
    - None

但是某些系统输出的线程转储具有以下格式,由于使用破折号而不是白色跟踪的格式更改,分析器将无法解析该格式 space。我还尝试用 TDA and Samurai 解析下面的文件,但没有成功。

Attaching to process ID 31283, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.91-b14
Deadlock Detection:

No deadlocks found.

Thread 21765: (state = BLOCKED)
 - sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise)
 - java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long) @bci=20, line=215 (Compiled frame)
 - java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(java.util.concurrent.SynchronousQueue$TransferStack$SNode, boolean, long) @bci=160, line=460 (Compiled frame)
 - java.util.concurrent.SynchronousQueue$TransferStack.transfer(java.lang.Object, boolean, long) @bci=102, line=362 (Compiled frame)
 - java.util.concurrent.SynchronousQueue.poll(long, java.util.concurrent.TimeUnit) @bci=11, line=941 (Compiled frame)
 - java.util.concurrent.ThreadPoolExecutor.getTask() @bci=134, line=1066 (Compiled frame)
 - java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=26, line=1127 (Compiled frame)
 - java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=617 (Compiled frame)
 - java.lang.Thread.run() @bci=11, line=745 (Compiled frame)

我的问题是:

  1. 为什么格式不同?是否是从 JVM 版本 24 到 25 的更改(显示在每个输出的顶部)。
  2. 是否有解析新格式的工具或以旧格式输出的未记录的 jstack 命令?

很可能您使用的转储之一是 -F 而另一个没有。它们是使用不同的机制获取的,因此输出可能会有所不同。

这是一个带 -F 的例子

$ jstack -F 75540
Attaching to process ID 75540, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.45-b02
Deadlock Detection:

No deadlocks found.

Thread 14611: (state = BLOCKED)


Thread 13571: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.ref.ReferenceQueue.remove(long) @bci=59, line=143 (Interpreted frame)
 - java.lang.ref.ReferenceQueue.remove() @bci=2, line=164 (Interpreted frame)
 - java.lang.ref.Finalizer$FinalizerThread.run() @bci=36, line=209 (Interpreted frame)

没有

$ jstack 75540
2016-11-09 09:03:31
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.45-b02 mixed mode):

"Attach Listener" #10 daemon prio=9 os_prio=31 tid=0x00007f81e4000000 nid=0x5503 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Service Thread" #9 daemon prio=9 os_prio=31 tid=0x00007f81e2815800 nid=0x5103 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

如果您好奇,可以在 Running jmap getting Unable to open socket file 中阅读更多关于差异的信息。 (输出的差异只是其结果)