2010-06-11 51 views
10

我有一個Java應用程序在使用時使用了大量內存,但是當程序未被使用時,內存使用率並未下降。使用App時Java內存使用增加,但未使用時不會減少

有沒有辦法強制Java釋放這個內存?由於當時並不需要此內存,因此我可以理解爲保留少量內存,但Java僅保留其曾經使用過的所有內存。它也會在以後重用這個內存,但是必須有一種方法來迫使Java在不需要時釋放它。

System.gc不起作用。

+2

System.gc只建議垃圾收集......它實際上並不強制垃圾收集。 – Ascalonian 2010-06-11 12:05:06

+0

檢查「free -m」可能它們中的很多都是緩存,你的堆正在上升並且通常用gc完成。 – Steve 2016-09-23 22:44:37

回答

7

正如在註釋中指出的那樣,當垃圾收集器處理對象時,它並不確定它是否將系統的內存給回給系統。

也許Tuning Garbage Collection Outline提供瞭解決問題的方法:

默認情況下,JVM增大或縮小堆在每個GC保留自由空間的比率在規定範圍內的每一個集合居住對象。

  • -XX:MinHeapFreeRatio - 當一代中可用空間的百分比低於這個值時,這一代將擴展到滿足這個百分比。默認值是40
  • -XX:MaxHeapFreeRatio - 當一代中可用空間的百分比超過此值時,代數將縮小以達到此值。默認值是70

否則,如果你懷疑你的泄漏引用你能找出什麼,在哪裏對象是如何泄露的,是監測JVisualVM堆(使用捆綁的工具標準SDK)。您可以通過此程序,請執行堆轉儲並在對象的內存消耗得到直方圖:

enter image description here

+0

優秀的點。我沒有這樣想過。更新了答案。 – aioobe 2010-06-11 12:23:54

0

System.gc沒有關於如果跑的時候就應該釋放所有的內存保證。請參閱Why is it bad practice to call System.gc()?

如果設置爲較大的值,請嘗試調整Xmx JVM參數,並查看JConsole中的內容以查看內存使用情況和GC活動情況。通常你會看到一個鋸齒圖案。

您可能還想使用探查器來查看內存的使用位置並識別泄漏。

0

發生以下兩件事之一:

1)您的應用程序泄漏引用。當你不再需要它時,你確定沒有掛在物體上嗎?如果這樣做,Java必須將它們保存在內存中。

2)Java的工作很好。你沒有從你沒有使用的記憶中獲益。

2

你是什麼記憶?如果它是RAM(而不是Java VM本身的堆空間使用量),那麼這可能是正常的。分配內存是一個相對昂貴的操作,所以一旦JVM得到了一些內存,即使它不是當時所需要的,它也不願意將其退回。

1

您是否考慮過使用內存分析器?如果您無法訪問其中一個,則可以先捕獲一堆jmap -histo <pid>並編寫一個腳本來計算差異。

相關問題