1

我有一个连接泄漏,幸运的是由 BEA WebLogic 捕获。但是,在阅读了一些文献之后,我仍然试图找出堆栈跟踪的哪一部分可能暗示我可能正在查看的代码的哪一部分。

        ####<May 21, 2011 1:16:06 PM EST> <Warning> <JDBC> <svrl003.sia.com> <svr3> <Finalizer> <<anonymous>> <> <BEA-001074> <A JDBC pool connection leak was detected. A connection leak occurs when a connection obtained from the pool was not closed explicitly by calling close() and then was disposed by the garbage collector and returned to the connection pool. The following stack trace at create shows where the leaked connection was created.  Stack trace at connection create:

        at weblogic.jdbc.wrapper.PoolConnection.init(PoolConnection.java:61)
        at weblogic.jdbc.pool.Driver.allocateConnection(Driver.java:254)
        at weblogic.jdbc.pool.Driver.connect(Driver.java:164)
        at weblogic.jdbc.jts.Driver.getNonTxConnection(Driver.java:540)
        at weblogic.jdbc.jts.Driver.connect(Driver.java:139)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:329)
        at com.oco.util.BEndOcDBConnectionPool.getConnection(BEndOcDBConnectionPool.java:188)
        at com.oco.util.BEndOcDBConnectionPool.getConnection(BEndOcDBConnectionPool.java:144)
        at com.oco.util.BEndConnectionManager.getConnection(BEndConnectionManager.java:38)
        at com.oco.ejb.confirmation.OrderConfirmationBean.saveConsents(OrderConfirmationBean.java:10213)
        at com.oco.ejb.confirmation.OrderConfirmationBean.saveConsents(OrderConfirmationBean.java:10172)
        at com.oco.ejb.confirmation.OrderConfirmation_9rmehc_EOImpl.saveConsents(OrderConfirmation_9rmehc_EOImpl.java:2178)
        at com.oco.ejb.confirmation.OrderConfirmation_9rmehc_EOImpl_WLSkel.invoke(Unknown Source)
        at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:492)
        at weblogic.rmi.cluster.ReplicaAwareServerRef.invoke(ReplicaAwareServerRef.java:108)
        at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:435)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
        at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:147)
        at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:430)
        at weblogic.rmi.internal.BasicExecuteRequest.execute(BasicExecuteRequest.java:35)
        at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
        at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
    > 

似乎表明我应该查看com.oco.ejb.confirmation.OrderConfirmationBean.saveConsents,但是,我可以确定它可能是com.oco.ejb.confirmation.OrderConfirmationBean.saveConsents吗?

谢谢!

4

3 回答 3

2

堆栈跟踪始终向您显示当前线程在该时间点正在做什么。因此,逐行查看堆栈跟踪对于您的特定问题来说是一个很好的调查路线。

您的堆栈跟踪中有 5 条操作行供您理解 - 我将介绍这些行。

at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:329)

这是 Weblogic 内部类,表示开始从池中获取连接的调用,此时 Weblogic 意识到由于泄漏而没有可用的连接

at com.oco.util.BEndOcDBConnectionPool.getConnection(BEndOcDBConnectionPool.java:188)
at com.oco.util.BEndOcDBConnectionPool.getConnection(BEndOcDBConnectionPool.java:144)
at com.oco.util.BEndConnectionManager.getConnection(BEndConnectionManager.java:38)

这些是您的应用程序代码中的 3 行代码,它是一个用于获取连接的 ConnectionManager。我想这主要负责管理您的应用程序中的所有 JDBC 连接 - 所以这就是您应该查看哪里出了问题的地方。

at com.oco.ejb.confirmation.OrderConfirmationBean.saveConsents(OrderConfirmationBean.java:10213)

OrderConfirmationBean saveConsents 方法的此特定行号 10213正在调用BEndConnectionManager- 这本身可能不是问题,当它进行调用时会发生什么导致问题。

因此,回顾一下,从第 10213 行开始,OrderConfirmationBean saveConsents您会看到 BEndConnectionManager 调用可能不会关闭连接 - 现在检查您的代码以查看关闭连接是否已完成 或是否需要自行 完成。OrderConfirmationBeanBEndConnectionManager

参考 BEA-001074 的更新

我更关注堆栈跟踪而不是 BEA-001074。

因此,BEA-001074 是垃圾收集器 (GC) 运行时抛出的终结器消息。所以我对发生的事情的理解是:

代码中使用了连接但未关闭,因此 Weblogic 服务器的 JVM 堆中保留了一些引用。一段时间后,当 GC 运行时,它意识到连接不再处于活动状态,并在垃圾收集之前运行终结器。BEA 然后抛出错误BEA-001074,通知我们通过破坏引用并将连接返回到池中已经堵塞了潜在的泄漏。

为了澄清您的问题,这似乎不是在获取新连接时,正如我最初的回答所建议的那样。

Weblogic 能够重现一个堆栈跟踪,该堆栈跟踪指的是连接(应该已经关闭)实际打开的点。

Oracle 论坛上的一些阅读表明,在 8.1 的某些版本中,他们无法重现堆栈跟踪,这显示了Null exception passed- 所以在你的情况下,你可以看到实际的堆栈是好的并且可以工作。

于 2011-05-23T06:09:53.463 回答
1

确保你真正释放你的连接。确保在 try/catch 块中使用 finally 块来释放连接以捕获异常情况。

于 2011-05-23T04:42:25.293 回答
0

避免使用终结器,请参阅 Bloch 的《Effective Java》一书。无法保证终结器何时运行,因此您保持连接的时间可能比您想象的要长,从而导致泄漏

于 2018-10-02T16:38:11.060 回答