在分析 Java 应用程序时,我注意到一个有趣的事实。当 JVM 处于死亡线程转储的 GC 螺旋中时,它看起来像:
"1304802943@qtp-393978767-9985" prio=10 tid=0x00007f3ed02dd000 nid=0x74e7 in Object.wait() [0x000000004febb000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:626)
- locked <0x00000007aed40048> (a org.mortbay.thread.QueuedThreadPool$PoolThread)
"26774405@qtp-393978767-9984" prio=10 tid=0x00007f3ee4b37000 nid=0x74e6 in Object.wait() [0x0000000045d1a000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:626)
- locked <0x00000007aed83aa0> (a org.mortbay.thread.QueuedThreadPool$PoolThread)
"764808089@qtp-393978767-9983" prio=10 tid=0x00007f3ee4c50000 nid=0x74e5 in Object.wait() [0x000000004ad6a000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:626)
- locked <0x00000007aed5c448> (a org.mortbay.thread.QueuedThreadPool$PoolThread)
因此,有很多线程处于TIMED_WAITING
状态。从理论上讲,在正常运行的应用程序中很容易发现这种情况(应用程序目前根本没有任何传入请求),但我什至找不到单个请求调度线程做一些有用的事情(标称命中率约为 100 hps)。
这种行为与GC有什么关系,还是只是巧合?
最佳答案
只回答问题的标题:
What does thread dump look like when JVM spent time in GC?
答案是:你没有办法获得这样的转储(以通常的方式)。
JVM 只有在到达 safepoint 后才处理线程转储请求这在 GC 中是不可能发生的。
但是有一种欺骗方法可以借助未记录的 JVMTI 函数 AsyncGetCallTrace 获取 Activity GC 的线程转储,该函数在这篇文章中提到:
http://jeremymanson.blogspot.com/2010/07/why-many-profilers-have-serious.html
它还暗示Oracle Solaris Studio可以be used采取这种混合的 native /java 线程转储。
关于java - 当 JVM 花费时间在 GC 中时,thread dump 是什么样子的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8412303/