2010-04-11 94 views
4

這是運行ActiveMQ的JVM(win64,6u17)的屏幕截圖,每次垃圾收集後堆大小都會減少。隨着堆大小的減少,垃圾收集變得更加頻繁,堆減少得更快。最終虛擬機鎖定,因爲它花費所有的時間在GC。Java堆不斷縮小!這個堆大小的圖表中發生了什麼?

-Xms是默認值,-Xmx是2048mb。

發生了什麼!!?我怎樣才能避免這種情況?

http://imagebin.org/92614

Shrinking heap http://imagebin.org/index.php?mode=image&id=92614

NB最初發佈於serverfault.com,搬到stackoverflow.com的要求

回答

6

谷歌找到了我的下面,從IBM JVM FAQ(怎麼就這麼一個NLA ):

何時e Java堆縮小?

當GC確定存在大量的空閒堆存儲並釋放一些堆內存有利於系統性能時,會發生堆縮減。在GC之後發生堆縮小,但是當所有線程仍然被掛起時。

Sun JVM做了類似的事情。以下是Oracle技術網文章Ergonomics in the 5.0 Java Virtual Machine的摘錄。

堆將增長或縮小到一定的大小,以支持所選的吞吐量目標。預計在初始化期間和應用程序行爲發生變化期間堆大小的一些振盪。

...

典型的是作爲垃圾收集器試圖滿足競爭的目標堆的大小會振盪。即使應用程序已達到穩定狀態,情況也是如此。達到吞吐量目標(可能需要更大的堆)的壓力與最大暫停時間和最小佔用空間(這兩者可能需要一個小堆)的目標相競爭。

我建議你看看該文件的其餘部分;它可能會有更多與您的問題相關的信息。

0

只是猜測: 它看起來像系統是非常閒置。可能有一些緩存正在進行,並且緩存中的內容會從緩存中刪除並獲得gc'd。或者因爲它是一個排隊系統,也許它在隊列中有一些消息,這些消息在之後慢慢地被傳送並被gc'd。

gc-runs的頻率增加可能是由於系統負載不斷減少。

至於如何避免它。你爲什麼要避免它?看起來你的CPU負載爲零。所以你可以自由地讓gc做任何想做的事

+1

我認爲,「最終虛擬機鎖定」(如果真實並且如同OP所述)將會是需要避免的。 – 2010-04-11 17:16:33

+0

該死的,你是對的,完全錯過了那部分 – 2010-04-12 07:55:05

6

有一個JVM參數來控制堆的大小。

-XX:MaxHeapFreeRatio

的默認值,這是70.遊離比例的空間在總堆大小在堆上未分配的量。它的可用空間百分比上升到70%的默認值以上,jvm將減少堆的大小,以允許操作系統使用內存。

如果堆被過於頻繁地萎縮,你可以增加-XX值:MaxHeapFreeRatio。如果它設置爲100,它可能永遠不會收縮。