包含处于 RUNNABLE 状态且没有堆栈的线程的线程转储
Thread dump containing threads in RUNNABLE state with no stack
使用 CPU 在高负载应用程序上执行线程转储,我看到很多线程处于这种状态:
"ajp-executor-threads - XXXXXX" prio=10 tid=0x00002b04b8b33801 nid=0x5327 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
对我来说真正奇怪的是根本没有堆栈跟踪并且ajp-thread的总数高于max-threads(下)配置
应用程序 运行 发生在:
- JBoss 7
- Java7u75
- 红帽 5.11
- 运行 在 VMWare Enterprise/vSphere 5.5 上
执行器配置为:
<subsystem xmlns="urn:jboss:domain:threads:1.1">
<bounded-queue-thread-pool name="ajp-executor">
<core-threads count="32"/>
<queue-length count="1"/>
<max-threads count="300"/>
<keepalive-time time="5" unit="seconds"/>
</bounded-queue-thread-pool>
</subsystem>
请注意,此主机上的负载非常高:
CPU达到70%
负载为 4(== vCPU 的数量)
请注意这些线程不是空闲线程,因为空闲线程具有以下堆栈跟踪:
"Reference Handler" daemon prio=5 tid=0x00007f92cb00e800 nid=0x3703 in Object.wait() [0x000000012057e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007aaa84470> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked <0x00000007aaa84470> (a java.lang.ref.Reference$Lock)
这些是 AJP 执行程序连接池中的空闲线程。您已将核心线程设置为 32,这意味着池将始终在连接池中维护 32 个线程,尽管它们可能处于空闲状态。根据您的配置,您最多可以看到 300 个线程,但任何超过 32 个的线程只会等待 5 秒,然后就会死亡并从连接池中删除。
至于你的 CPU 负载,我怀疑它与这些空闲连接池线程有任何关系。
请在此处查看 John Skeet 的回答,了解有关连接池和保持活动状态的更多信息:
经过进一步分析,我发现问题是由于通过以下方式启用了远程调试:
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=XXXXXXX
这解释了线程转储中这些奇怪的空堆栈跟踪。
使用 CPU 在高负载应用程序上执行线程转储,我看到很多线程处于这种状态:
"ajp-executor-threads - XXXXXX" prio=10 tid=0x00002b04b8b33801 nid=0x5327 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE
对我来说真正奇怪的是根本没有堆栈跟踪并且ajp-thread的总数高于max-threads(下)配置
应用程序 运行 发生在:
- JBoss 7
- Java7u75
- 红帽 5.11
- 运行 在 VMWare Enterprise/vSphere 5.5 上
执行器配置为:
<subsystem xmlns="urn:jboss:domain:threads:1.1">
<bounded-queue-thread-pool name="ajp-executor">
<core-threads count="32"/>
<queue-length count="1"/>
<max-threads count="300"/>
<keepalive-time time="5" unit="seconds"/>
</bounded-queue-thread-pool>
</subsystem>
请注意,此主机上的负载非常高:
CPU达到70%
负载为 4(== vCPU 的数量)
请注意这些线程不是空闲线程,因为空闲线程具有以下堆栈跟踪:
"Reference Handler" daemon prio=5 tid=0x00007f92cb00e800 nid=0x3703 in Object.wait() [0x000000012057e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007aaa84470> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked <0x00000007aaa84470> (a java.lang.ref.Reference$Lock)
这些是 AJP 执行程序连接池中的空闲线程。您已将核心线程设置为 32,这意味着池将始终在连接池中维护 32 个线程,尽管它们可能处于空闲状态。根据您的配置,您最多可以看到 300 个线程,但任何超过 32 个的线程只会等待 5 秒,然后就会死亡并从连接池中删除。
至于你的 CPU 负载,我怀疑它与这些空闲连接池线程有任何关系。
请在此处查看 John Skeet 的回答,了解有关连接池和保持活动状态的更多信息:
经过进一步分析,我发现问题是由于通过以下方式启用了远程调试:
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=XXXXXXX
这解释了线程转储中这些奇怪的空堆栈跟踪。