我试图理解在java11的jstack线程转储中“cpu”和“elapsed”字段的含义。我有一个线程的以下细节,其中jstack被快速执行了三次:
"Thread 1 " daemon prio=5 os_prio=0 cpu=0.13ms elapsed=51.03s tid=0x00007fe9c4024000 nid=0x2c11 waiting on condition [0x00007fe500284000]
java.lang.Thread.State: TIMED_WAITING (parking)
"Thread 1 " daemon prio=5 os_prio=0 cpu=0.13ms elapsed=56.96s tid=0x00007fe9c4024000 nid=0x2c11 waiting on condition [0x00007fe500284000]
java.lang.Thread.State: TIMED_WAITING (parking)
"Thread 2" daemon prio=5 os_prio=0 cpu=0.10ms elapsed=1.35s tid=0x00007fe9c4024000 nid=0x2da1 waiting on condition [0x00007fe4a0311000]
java.lang.Thread.State: TIMED_WAITING (parking)
在TIMED_WAITING之后,消息的其余部分在所有三个线程中完全相同。我的问题是,为什么经过的时间在第三个1突然减少,即使tid是相同的?在我的应用程序中,线程名一直在变化,所以这并不一定意味着不同的线程名对应于不同的线程。会不会发生旧线程死亡而同一tid被快速重用的情况?如果有人能把任何官方文件链接到对转储的解释上,那将是很有帮助的。(注意:我的线程属于一个线程池)
我只能在https://bugs.openjdk.org/browse/JDK-8200720找到cpu和经过的解释。但没什么用。
1条答案
按热度按时间cx6n0qe31#
第三个输出显然包含一个不同的线程。如果您不信任其他名称,请信任其他
nid
。此外,假定输出“elapsed = 1.35s”,它的字面意思是线程在此时只运行了一秒多一点,因此线程在jstack
调用之间启动是完全合理的。如果第三个
jstack
输出不包含第一个线程,并且您没有过滤,则表明第一个线程在第二次和第三次调用之间终止,这解释了为什么这两个线程可以具有相同的tid
。由于这不是线程id而是内存地址,因此释放旧线程对象允许将内存重新用于新线程对象。如前所述,使用
nid
来确定您正在查看的是相同的线程还是不同的线程。你可以在互联网上找到不同的文章解释属性,但我找不到一个有资格作为官方文档,虽然。