如何指出是啥在线程转储文件中将线程置于 WAITING 状态

Posted

技术标签:

【中文标题】如何指出是啥在线程转储文件中将线程置于 WAITING 状态【英文标题】:How to point out what's putting a thread in a WAITING state in a threadump file如何指出是什么在线程转储文件中将线程置于 WAITING 状态 【发布时间】:2018-11-04 16:18:13 【问题描述】:

我在 aws m4.xlarge 上有一个可信赖的 linux,所以 4 CPU,16 GB RAM。它在 tomcat7 和 oracle java 8 上运行 java 应用程序。

该应用经常挂起并且不接受任何其他连接。由于响应超时,状态蛋糕将报告为关闭。 Datadog 将显示线程已满。但是 CPU 没有增加(仅占使用率的 10%)。在此期间 RAM 使用量保持不变。

只有重新启动 tomcat 才能暂时解决问题(大约 12 小时)。所以我做了一个线程转储,看到这么多线程处于等待状态。由于这对我来说很新,即使有数据我也很盲目。

我希望我能在这里得到帮助并最终掌握加密线程转储文件的艺术。我已将其附在此处,并将其上传到fastthread.io and it says there is no problem。我也上传了完整的threadump on zerobin

如果这里有人能对此有所了解,我将不胜感激,我希望它能帮助处于同样情况的其他人。提前致谢。

【问题讨论】:

【参考方案1】:

很多线程都处于 WAITING 状态,对它们来说绝对没问题。例如,有些线程具有以下堆栈跟踪:

...
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)
...

这仅表示线程正在等待任何要执行的任务。

但是,其他堆栈看起来并不好。

java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.**awaitAvailable**(BasicResourcePool.java:1414)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:606)
- locked <0x000000055c2d3ce0> (a com.mchange.v2.resourcepool.BasicResourcePool)
at 
com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:526)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:755)

那些线程正在等待池中的空闲连接。 C3P0 是一个数据库连接池。它们不是每次都创建一个新连接,而是缓存在池中。关闭时,连接本身并没有关闭,而只是返回到池中。因此,如果由于某种原因休眠(或其他用户)在释放连接后没有关闭连接,则池可能会耗尽。

为了解决问题,您必须找出使用后某些连接没有关闭的原因。尝试查看您的代码来执行此操作。

另一种选择是暂时不使用 C3P0(池化)。这不是永远的,但至少你可以检查一下这个猜测是否正确。

【讨论】:

将审查 C3P0 属性并从本地机器上通过 JConsole 执行一些 JMX 以查看我们是否可以确认此断言。然而,不幸的是,我不能没有游泳池。

以上是关于如何指出是啥在线程转储文件中将线程置于 WAITING 状态的主要内容,如果未能解决你的问题,请参考以下文章

如何使用jboss-eap-5.1服务器在Linux环境中进行线程转储

将线程的日志数据转储到公共缓冲区

当 Java 中存在堆溢出时,我如何知道啥在使用内存?

“;”的目的是啥在 for 循环结束时?

是啥在 mongodb 中创建了默认的 ObjectID?

是啥在 mongodb 中创建了默认的 ObjectID?