2011-08-08 33 views
3

我試圖追蹤我的web應用程序中導致PermGen空間填滿並拋出OutOfMemoryError:PermGen大小後,幾次重新加載內存泄漏。現在我知道我可以停止/啓動整個Tomcat實例,但我試圖找出內存泄漏的原因。Tomcat WebappClassloader沒有垃圾收集

我讀過這篇文章http://java.dzone.com/articles/memory-leak-protection-tomcat這表明我必須確保在停止我的應用程序之後,應該沒有對WebappClassLoader的未完成引用,這會阻止它被垃圾收集。使用YourKit和內存分析器我發現了一些在第三方庫中發生並修復它們的情況。

我現在正處於兩個工具都報告沒有從GC根到對象(WebappClassloader)的路徑的地步,但WebappClassloader仍然沒有被垃圾收集!任何人遇到過這樣的事情?

我使用Tomcat 6.0.32

+0

Tomcat的源代碼[JreMemoryLeakPreventionListener](http://www.jarvana.com/jarvana/view/org/apache/tomcat/tomcat-catalina/7.0.0/tomcat-catalina-7.0.0-sources.jar !/org/apache/catalina/core/JreMemoryLeakPreventionListener.java?format = ok)提及'XML解析可以將web應用程序類加載器固定在內存中。這尤其令人討厭,因爲分析器(至少YourKit和Eclipse MAT)不會識別與此相關的GC根源。所以我知道它可能發生,但是當它發生時該怎麼辦? –

+0

在YourKit未能顯示任何更明顯的GC根源之後,幫助我的東西是強制GC(使用YourKit,JConsole等),拍攝快照並在其中搜索我們自己的任何類 - 這些通常在原點處暗示的內存泄漏。 –

+0

謝謝,我會試一試,讓你知道結果! –

回答

1

對不起,我沒有解決這個早...

我已經消除了所有的GC根WebappClassloader的,但它只是沒有被garbage-集。我試圖強制垃圾收集,無濟於事。

問題在於調用Runtime.getRuntime().gc();並不保證所有可能的東西都會被垃圾回收 - 只有JVM會盡其最大努力。

將Tomcat重新加載了幾次之後,JVM在PermGen空間上開始運行低,WebappClassloader確實被垃圾收集。我假設JVM之前沒有GC,因爲它不需要。