狩猎内存泄漏,VisualVM:"没有发现GC根".下一步是什么?

kan*_*kan 12 java memory-leaks visualvm

我有一个内存转储,我从一个垂死的应用程序.它消耗了所有可用堆(-Xmx1024m).它用于com.gargoylesoftware.htmlunit.WebClient抓取网页.每分钟发出一些http请求,几天后就会死掉.正如我从转储中看到的那样,它有~1750个HtmlPage类实例,每个实例都有相关对象的音调,包括已爬网页面的完整内容.

我无法理解为什么HtmlPage不收集垃圾.我已经调查了实例引用,我没有看到任何我的代码持有对它的引用,并且VisualVM说"找不到GC根".据我所知,它应该意味着该对象符合gc的条件,但它不起作用.

应用程序作为一个简单的独立进程运行,它不使用任何Web容器或应用程序服务器.

任何提示?我还应该研究什么?

眼镜:

  • htmlunit v2.7
  • java版"1.6.0_13"Java(TM)SE运行时环境(版本1.6.0_13-b03)Java HotSpot(TM)服务器VM(版本11.3-b02,混合模式)
  • Linux my.lan 2.6.18-128.el5#1 SMP Wed Dec 17 17:42:39 EST 2008 i686 i686 i386 GNU/Linux

UPDATE1

我试图通过YourKit Java Profiler分析转储.它向我展示了许多java.lang.ref.Finalizer具有310mb保留大小的对象.它们是为net.sourceforge.htmlunit.corejs.javascript.NativeGenerator#finalize()终结者创建的,然后NativeGenerator指向Window,然后HtmlPage指向一切.

有谁知道他们为什么留在记忆中?

注意:好奇,但VisualVM显示"待定完"为零.

max*_*dim 1

确保在完成页面后调用 webClient.closeAllWindows() - 否则 JavaScript 线程将继续运行,并保留对页面资源等的引用。