是内存泄漏? 为什么java.lang.ref.Finalizer会吃这么多的内存

我在程序上运行了一个堆转储。 当我在内存分析工具中打开它时,我发现org.logicalcobwebs.proxool.ProxyStatementjava.lang.ref.Finalizer占用了大量内存。 这是为什么?

截图

一些类实现了Object.finalize()方法。 重写此方法的对象需要由后台线程调用终结器调用,并且在这种情况发生之前无法清理。 如果这些任务很短,而且不丢弃其中的许多,那么这一切都可以正常工作。 但是,如果要创build大量这些对象和/或它们的终结器需要很长时间,则将构build最终的对象队列。 这个队列有可能用完所有的内存。

解决scheme是

  • 如果可以的话,不要使用finalize()d对象(如果你正在编写对象的类)
  • 使最终确定非常短(如果你必须使用它)
  • 不要每次丢弃这样的对象(试着重新使用它们)

在使用现有的库时,最后一个选项对您来说可能最适合。

从我所能做出来的,Proxool是一个JDBC连接的连接池。 这表明问题是你的应用程序正在滥用连接池。 而不是调用close语句对象,您的代码可能会丢弃他们和/或他们的父连接。 Proxool依靠终结器来closures底层驱动程序实现的对象…但是这需要那些Finalizer实例。 这也可能意味着您正在导致连接打开/closures(实际)数据库连接的次数比所需的次数多,这会对性能造成影响。

所以我build议你检查你的代码是否泄露了ResultSet,Statement和/或Connection对象,并确保你在finally块中closures它们。


看看内存转储,我希望你关心的是898,527,228字节在哪里。 绝大多数都由Finalizer对象保留,其ID是2aab07855e38 。 如果您仍然有转储文件,请查看 Finalizer所指的内容。 它看起来比Proxool对象更有问题。