2011-12-02 97 views
23

我正在研究Java中的內存使用情況,以瞭解爲什麼我的程序會泄漏內存。在我的主while循環中剝離代碼後,我仍然會隨着時間的推移增加內存使用量。思考一個空的程序的內存使用情況:爲什麼空的Java程序會消耗內存?

class Nothing 
{ public static void main(String[] args) 
    { while(true); } 
} 

我仍然認爲增加的內存:

Image description here

所以我的問題是:爲什麼仍鋸齒模式?爲什麼當GC運行時不能保存所有的內存(每次gc運行(谷))時使用的內存增加10-20Kb(與之前的谷相比))?

編輯:

Java版本 「1.6.0_29」

的Java(TM)SE運行時環境(建立1.6.0_29-B11)

的HotSpot的Java(TM)客戶端虛擬機(構建20.4-B02,混合模式,共享)

OS:Windows 7企業-32位

+0

我沒有看到增加。記憶力上升,然後收集下來。它看起來像使用的最大內存隨着時間的推移是不變的。 –

+0

另一個嘗試在應用程序中查找內存泄漏的工具是[Plumbr](http://plumbr.eu)。它應該比摔跤探測器更容易,並試圖從所有這些信息中推斷出某些東西。 – Nikem

回答

10

爲什麼仍然有鋸齒形圖案?

如果我沒有弄錯,部分原因是監視器本身迫使應用程序創建包含有關垃圾收集和內存使用狀態信息的臨時對象。

爲什麼當GC運行它不會保存所有的內存(每次gc運行(谷))使用的內存增加10-20Kb(與前一個谷相比))?

我相信監視器不會立即看到垃圾收集後使用的內存量,而是必須經常輪詢以查看內存使用情況。因此,感知的「山谷」肯定比真實的山谷要高一些。我會猜想谷的內存使用感知增加只是這種差異的隨機產物,並會隨着時間而被中和。 (也就是說,我不認爲每個週期實際存在10-20 KB的內存泄漏。)

+0

那麼,我將如何獲得關於引擎蓋下正在發生的事情的更準確圖片? – GoldfishGrenade

+0

在真正的程序中,還是在你的無操作迴路測試程序中?在真正的程序中,堆轉儲將幫助您找出哪些對象無法被垃圾收集,這可以幫助您確定程序的哪些部分可能會被指責。 – ruakh

+0

+1這絕對是由於管理bean和任何用來與它們對話的協議(可能是RMI,因爲它是默認的)所導致的。 – Fredrik

4

這是探查器的工件,沒有探查器就沒有分配。不同的配置文件會產生不同的工件,具體取決於它們如何記錄數據。下面你看到的JProfiler的外觀輪廓Nothing像:

enter image description here

少很多鋸齒狀花紋。然而,也有極小的內存消耗:

enter image description here

這是由於配置代理輪詢java.lang.management.MemoryUsage JMX豆。最終,這種消耗也會觸發垃圾收集。