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

fuy*_*001 60 java memory finalizer proxool

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

截图

Pet*_*rey 64

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

解决方案是

  • 如果可以,请不要使用finalize()d对象(如果您正在为对象编写类)
  • 最终确定很短(如果你必须使用它)
  • 不要每次丢弃此类对象(尝试重新使用它们)

当您使用现有库时,最后一个选项可能最适合您.

  • 选项#4 - 避免使用(过度)使用终结器的库. (17认同)
  • 选项#1的变体;) (6认同)
  • 当我使用大量正则表达式模式/匹配器实例(在使用后立即发布)时,我注意到Android上发生了这种情况,当我内存不足时,我看到50%的堆被这些FinalizerReferences占用,指向任一个我的Pattern或Matcher实例(堆映射中的那些对象不存在其他引用). (3认同)

Ste*_*n C 10

从我可以看出,Proxool是JDBC连接的连接池.这告诉我,问题是你的应用程序是在滥用连接池.close您的代码可能正在删除它们和/或它们的父连接,而不是调用语句对象.Proxool依靠终结器来关闭底层驱动程序实现的对象......但这需要那些Finalizer实例.这也可能意味着您导致连接更频繁地打开/关闭(实际)数据库连接,这对性能不利.

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


看看内存转储,我希望你关注的是898,527,228字节的去向.绝大多数都由ID为的Finalizer对象保留2aab07855e38.如果您仍然有转储文件,看看什么 Finalizer被提及.它看起来比Proxool对象更有问题.