linux - 如何指出是什么在线程转储文件中将线程置于 WAITING 状态
问题描述
我在 aws m4.xlarge 上有一个可信赖的 linux,所以 4 CPU,16 GB RAM。它在 tomcat7 和 oracle java 8 上运行 java 应用程序。
该应用程序经常会挂起并且不会接受任何其他连接。由于响应超时,状态蛋糕将报告为关闭。Datadog 将显示线程已满。但是 CPU 没有增加(仅占使用率的 10%)。在此期间 RAM 使用率保持不变。
只有 tomcat 重启可以暂时解决问题(大约 12 小时)。所以我做了一个线程转储,看到这么多线程处于等待状态。由于这对我来说很新,即使有数据我也很盲目。
我希望我能在这里得到帮助并最终掌握加密线程转储文件的艺术。我已经把它附在这里了,我也把它上传到了fastthread.io,它说没有问题。我还在zerobin 上上传了完整的线程转储
如果这里的任何人都可以对此有所了解,我将非常感激,我希望它可以帮助处于相同情况的其他人。提前致谢。
解决方案
很多线程都处于 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(池化)。这不是永远的,但至少你可以检查这个猜测是否正确。
推荐阅读
- c++ - 指向数组的unique_ptr是否会在调用release()后自动释放动态内存?
- java - 如何修复位置在某些手机中每秒发送一次数据?
- python - Python:file:unbound 方法 __str__() 必须以 xDef 实例作为第一个参数调用(取而代之的是 classobj 实例)
- r - 如何在 R 中反映函数中的长参数
- java - 使用基于列名(标题)的 java 将几列从一个 CSV 复制到另一个 CSV
- android - AndroidX 中的持久底页
- git - 将代码从 gitlab 同步或更新到 Azure 存储库
- node.js - 处理大型 XLSX 文件:Node.js 中超出了最大调用堆栈
- r - 从一列值在 R 中创建一个二进制变量
- swift - 嗨,伙计们需要帮助,我怎么能用 swift alamofire 解析这个响应