Java 应用程序使用 ojdbc6.jar、tomcat 7、tomcat-dbcp-8.0.3.jar(以及其他可能与此问题无关的 jar)、JDK 7 (u51)
我们已使用 v$session 报告确定存在连接泄漏,其中某些连接进入 INACTIVE 状态超过 7 小时。卡住状态下的线程转储也证实了这一点。
堆转储(在卡住状态下获取)显示:
- PoolableConnection 和 DefaultPooledObject 的总数等于 maxTotal(耗尽池的预期值)
- 每个连接都关联到 PooledObjectState ALLOCATED (预期)
- lastReturnTime = lastUserTime = lastBorrowedTime(在 DefaultPooledObject),对我来说意味着:THREAD-1(良好的工作流程) 返回由 THREAD-2 立即借用的连接 (有泄漏的糟糕工作流程)并且 THREAD-2 从未关闭 连接,让它悬空!
以上所有观察都是有道理的,因为我们肯定有连接泄漏和最终耗尽的池
我的问题是: 当我看到有关 PoolableConnection 的详细信息时,它具有关联的 boolean 值 _closed,即“true”。为什么/怎么会有“_closed = true”。 当我反编译 tomcat-dbcp jar 时,我可以看到每次 _closed 标记为 true 时,它也会将 IDLE 状态关联到连接对象(而不是 ALLOCATED)。
寻找有关此 boolean 值为何为真的理论。
PS:我们有各种想法(比如设置 logAbandoned)来找到导致连接泄漏的确切代码段,我期待找到堆转储捕获这些 PoolableConnection _closed=true 案例的原因(或理论)。
最佳答案
查看DelegatingConnection source code可以看出 closed=true
可以设置为 connection.close()
的结果,或者在一些异常之后的 finally
block 中设置为一项安全措施。
} finally {
closed = true;
}
存在泄漏,连接处于不一致状态,因为它无法关闭,可能已准备好在 ABANDONED 生命周期阶段进行处理。
通过 JMX 检查池可以提供另一个视角。
泄漏可能与处理不当的异常有关,否则会提示池状态不佳。
关于java - tomcat dbcp _closed PoolableConnection 但处于已分配状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52347117/