我在程序上运行了堆转储。当我在内存分析器工具中打开它时,我发现java.lang.ref.Finalizer
的{{1}}占用了大量内存。为什么会这样?
答案 0 :(得分:61)
某些类实现了Object.finalize()
方法。覆盖此方法的对象需要由后台线程调用终结器调用,并且在发生这种情况之前无法清除它们。如果这些任务很短并且您没有丢弃其中的许多任务,那么一切都很顺利。但是,如果要创建大量这些对象和/或它们的终结器需要很长时间,则要完成的对象队列会建立起来。该队列可能会占用所有内存。
解决方案是
当您使用现有库时,最后一个选项可能最适合您。
答案 1 :(得分:8)
据我所知,Proxool是JDBC连接的连接池。这告诉我,问题是你的应用程序是在滥用连接池。您的代码可能正在删除它们和/或它们的父连接,而不是在语句对象上调用close
。 Proxool依靠终结器来关闭底层驱动程序实现的对象......但这需要那些Finalizer实例。这也可能意味着您导致连接比必要更频繁地打开/关闭(实际)数据库连接,这对性能不利。
因此,我建议您检查泄漏的ResultSet,Statement和/或Connection对象的代码,并确保在finally
块中关闭它们。
查看内存转储,我希望你关注的是898,527,228字节的去向。绝大多数都由ID为2aab07855e38
的Finalizer对象保留。如果您仍然拥有转储文件,请查看 Finalizer
所指的。它看起来比Proxool对象更有问题。