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

时间:2011-12-02 10:40:16

标签: java memory finalizer proxool

我在程序上运行了堆转储。当我在内存分析器工具中打开它时,我发现java.lang.ref.Finalizer的{​​{1}}占用了大量内存。为什么会这样?

screenshot

2 个答案:

答案 0 :(得分:61)

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

解决方案是

  • 如果可以,请不要使用finalize()d对象(如果您正在为对象编写类)
  • make finalize很短(如果你必须使用它)
  • 每次都不要丢弃这些物品(尝试重复使用)

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

答案 1 :(得分:8)

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

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


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