2011-11-22 26 views
1

我的應用程序中存在嚴重的內存泄漏。我已經運行JMAP,它說,目前有以下對象,不應該在那裏(並且是泄漏的主要來源):垃圾收集器對象的內存泄漏

java.lang.management.MemoryUsage - 3938500 instances, 189048000 bytes 
[Ljava.lang.management.MemoryUsage - 787700 instances, 31508000 bytes 
com.sun.management.GCInfo - 293850 instances, 22055600 bytes 
sun.management.GCInfoCompositeData - 393850 instances, 12603200 bytes 

我不直接使用這些對象。但是垃圾收集器使用它們。 我使用:

Java version: 1.7.0-b147 
VM version: Java Hotspot(TM) 64-bit Server VM (build 21.0-b17, mixed mode) 
The application is run in Jetty version 7.3.1 

我使用目前Concurrent低暫停垃圾回收器。但是,即使在運行吞吐量收集器時,我也遇到了同樣的問題。

你知道爲什麼這些對象留在內存中嗎?你會建議做什麼?

UPDATE:內存泄漏仍會發生與Java 1.7更新1(1.7.0_01-B08,爪哇熱點(TM)64位服務器VM(構建21.1-B02,混合模式))

更新2:內存泄漏是由JConsole引起的。在JConosole啓動之前,沒有上述類的實例。一旦我通過JConsole連接到應用程序,對象就開始出現在內存中,並且它們永遠保持在那裏。在關閉JConsole之後,對象仍在內存中,並且它們的數量不斷增加,直到應用程序關閉。

+0

有在熱點編譯器循環優化的錯誤。這可能是問題的原因。升級到1.7.1 –

+1

GC不使用這些類。但是,監視GC的組件使用這些類來獲取有關GC的信息。 –

+0

我猜想這些是啓用GC跟蹤的人工產物。 –

回答

4

我沒有真正使用jmap,但我已經處理了我們的應用程序中的內存泄漏。

您的應用程序是否內存不足?我建議傾倒在應用程序關閉之前,以下內容添加到您的虛擬機ARGS

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp

當你的應用程序進入OOM,它會創建tmp下,您可以使用調試問題的HPROF文件。

如果它不走OOM,請嘗試分配一個較低的內存,以便強制一個OOM。

我用eclipse MAT來分析這個文件。這很好,因爲它會立即告訴你泄漏的懷疑。

+0

謝謝你的建議。我熟悉MAT,但它不能幫助我解決這個問題,因爲導致泄漏的物體不是我的。它們屬於java VM。順便說一句,你可以做堆轉儲,只要你想在JConsole中使用函數堆轉儲;)在這裏檢查http://download.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html – Palo

1

我認爲你需要提供更多的細節,以瞭解該應用的功能和功能。你只是使用jConsole來跟蹤這個問題?

我使用Visual VM來跟蹤這些類型的問題。有關如何將其用於內存泄漏的信息,請參閱此link,以及此版本用於Visual VM主page

0

我有同樣的問題。我在2個月前做過調查,問題出在JAVA 7_0虛擬機上。在我的場景中,java.lang.management.MemoryUsage對象掛起,每天增長數百MB。您看到掛起的所有其他對象都由java.lang.management.MemoryUsage對象引用。問題是,這個MemoryUsage對象只能掛在java 7_0和更高版本中,因爲這個MemoryUsage類已經被添加到JAVA 7中,並且從來沒有在java中使用。最重要的是,只有在使用JConsole連接到服務器後,此MemoryUsage類纔會掛在內存中。 JConsole第一次連接後,它創建了一些MemoryUsage跟蹤機制,它開始創建MemoryUsage對象。這些對象用於在JConsole中繪製漂亮的圖形。這沒關係。但是,問題是,JAVA 7是越野車,並且永遠不會釋放內存。 MemoryUsage對象永遠掛在堆上。關閉JConsole並不重要,它會在事後繼續增長。您第一次使用JConsole連接到JAVA 7_0進程時,您創建了該問題並且沒有解決方案。不要使用Jconsole或任何其他內存監視工具,也不要使用Java 7.在我的情況下,我註定要失敗,因爲我必須始終使用Jconsole,因爲JAVA 6對我來說不適合,因爲還有另一個bug,這使得由於鎖定對象而導致內存泄漏。我向ORACLE報告了這個bug,但是我不知道,如果他們知道了,並且正在解決它。我只是在等待更新版本的Java,所以我可以測試它,並停止每隔幾天重新啓動服務器。

+0

http://bugs.sun .com/bugdatabase/view_bug.do?bug_id = 7128632投票在這裏進行bug修復。 –

0

幾年前,我向Oracle報告了一個問題,在JDK 7中,在連接JConsole的那一刻就會出現內存泄漏。泄漏將永遠持續;即使斷開JConsole的連接也是如此。

什麼是泄漏?與垃圾收集器運行原因相關的對象。實際上大部分字符串(如「分配失敗」)。我只找到了問題,因爲我使用YourKit,在YourKit中,您可以分析被標記爲垃圾收集的對象。基本上這些對象並沒有被我的應用程序中的任何東西引用,但它們也沒有被垃圾收集器收集。

大多數堆轉儲工具立即從分析中刪除垃圾收集對象。因此YourKit對於確定該錯誤確實存在於JVM中至關重要。

找不到我的票,但我發現其他的: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7143760 http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7128632

相關問題