是内存泄漏吗?为什么java.lang.ref.Finalizer会消耗这么多内存

2022-08-31 14:23:38

我在我的程序上运行了一个堆转储。当我在内存分析器工具中打开它时,我发现 for 占用了大量内存。为什么会这样?java.lang.ref.Finalizerorg.logicalcobwebs.proxool.ProxyStatement

screenshot


答案 1

某些类实现该方法。重写此方法的对象需要由后台线程调用终结器调用,并且在发生这种情况之前无法清理它们。如果这些任务很短,并且您不会丢弃其中的许多任务,那么一切都可以很好地工作。但是,如果要创建大量这些对象和/或其终结器需要很长时间,则要完成的对象队列会堆积起来。此队列可能会耗尽所有内存。Object.finalize()

解决方案是

  • 如果可以的话,不要使用finize()d对象(如果你正在为对象编写类)
  • 使finize非常短(如果你必须使用它)
  • 不要每次都丢弃这些对象(尝试重用它们)

最后一个选项可能最适合您,因为您正在使用现有库。


答案 2

据我所知,Proxool是JDBC连接的连接池。这向我表明,问题在于您的应用程序正在滥用连接池。您的代码可能不是调用语句对象,而是删除它们和/或其父连接。Proxool依靠终结器来关闭底层驱动程序实现的对象...但这需要那些终结器实例。这也可能意味着您导致连接打开/关闭(实际)数据库连接的频率高于必要的频率,这对性能不利。close

因此,我建议您检查代码中是否有泄漏的 ResultSet、Statement 和/或 Connection 对象,并确保以块的形式关闭它们。finally


查看内存转储,我希望您关心的是898,527,228字节的去向。绝大多数由 id 为 的终结器对象保留。如果您仍然有转储文件,请查看指的是什么。它看起来比Proxool物体更有问题。2aab07855e38Finalizer