簡體   English   中英

狩獵內存泄漏,VisualVM:“沒有發現GC根”。 下一步是什么?

[英]Hunting memory leaks, VisualVM: “No GC root found”. What's next?

我有一個內存轉儲,我從一個垂死的應用程序。 它消耗了所有可用堆(-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分析轉儲。 它向我展示了許多具有310mb保留大小的java.lang.ref.Finalizer對象。 它們是為net.sourceforge.htmlunit.corejs.javascript.NativeGenerator#finalize()終結器創建的,而NativeGenerator是指Window ,然后是HtmlPage和所有內容。

有誰知道他們為什么留在記憶中?

注意 :好奇,但VisualVM顯示“待定完”為零。

確保在完成頁面后調用webClient.closeAllWindows() - 否則JavaScript線程將繼續運行,保持對頁面資源的引用等。

當一個對象具有非常重要的finalize()方法時,在創建對象的實例時,JVM會創建java.lang.ref.Finalizer,該java.lang.ref.Finalizer保存對創建的對象的引用,因此在finalize()方法完成之前它不會被垃圾收集。 內存泄漏來自那些沒有按時清除的java.lang.ref.Finalizer-s。 清除這些終結器是由一個具有較低優先級的單獨的終結器守護程序線程完成的,因此如果使用已實現的finalize()方法創建大量對象實例,則會導致內存不足。

它描述的非常好:

http://www.fasterj.com/articles/finalizer2.shtml

這是他們建議的解決方案:

“一個顯而易見的方法是增加”Finalizer“守護程序線程的優先級 - 沒有這個API,所以你必須遍歷所有線程才能按名稱找到它,然后增加它的優先級。”

祝好運

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM