我们在 JBoss 6.1 的 JDBC 池中发现了一个非常严重的泄漏。
这是由于代码依赖于close
连接上的方法来关闭底层语句。
尽管WrappedConnection确实关闭了它们,但代码如下所示:
if (statements != null) {
for (Iterator
<Map.Entry<WrappedStatement, Throwable>> i=statements.entrySet().iterator();
i.hasNext(); )
{
Map.Entry<WrappedStatement, Throwable> entry = i.next();
WrappedStatement ws= entry.getKey();
if (trackStatements==BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_TRUE_INT)
{
Throwable stackTrace = entry.getValue();
log.warn("Closing a statement you left open, please do your own housekeeping",
stackTrace);
}
try
{
ws.internalClose();
}
catch (Throwable t)
{
log.warn("Exception trying to close statement:", t);
}
}
}
statements 对象永远不会从其映射中删除语句,并且映射不断增长,并且这些语句保存结果集等(至少在我正在使用的 JDBC 驱动程序中)。
我想知道是否有人曾经用比这更强大的替代实现替换了 JBoss 中的 jdbc 池?
作为对此的一个小补充,代码和行为与结果集相同(基本上是复制和粘贴),尽管如果您不坚持任何时间长度的语句,内存泄漏可能并不严重(不像连接,按设计存在于池中)。