2014-09-12 24 views
6

enter image description herePS老代內存堆內存使用量:GC設置

下面是我的JVM設置:

JAVA_OPTS=-server -Xms2G -Xmx2G -XX:MaxPermSize=512M -Dsun.rmi.dgc.client.gcInterval=1200000 -Dsun.rmi.dgc.server.gcInterval=1200000 -XX:+UseParallelOldGC -XX:ParallelGCThreads=2 -XX:+UseCompressedOops -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jbos88,server=y,suspend=n 

問題: 總堆內存:2GB 老根:1.4GB(2/3的堆) 新一代:600MB(堆的1/3)

舊的內存增長超過70%的內存分配的大小和永遠不會受到甚至在100%即1.4GB的GC。 可以看到它下面的圖表,它從不是GC,內存的下降是從JConsole強制GC時發生的。 這個問題最終導致Web服務器關閉。

任何我錯過或錯誤設置JVM?

感謝您的幫助提前。

更新我的問題:

後堆分析看起來像有狀態會話bean是最大的嫌疑人: enter image description here 我們必須持有由Hibernate協助持久性邏輯狀態會話bean。

+0

你看到'OutOfMemoryError堆空間'的JVM終止嗎?或者你期待舊的GC能夠更早運行? – 2014-09-18 23:05:49

回答

3

enter image description here有狀態會話bean導致JVM內存不足。 使用@Remove註釋顯式處理它們可以解決此問題。

+0

你是怎麼找到它的? – Nageswaran 2016-04-28 10:29:30

4

GC將被最終調用,舊的gen幾乎不會被調用(因爲它非常慢)。 Gc確實運行,但它只會在新的gen和survivor gen上運行,它有一個完全不同的算法來清理舊的gen,這是比new/survivor gens更慢的算法。

這些數字真的很高,oldgen永遠不應該達到與newgen相比高的總和。 我的猜測是你有內存泄漏。

我只能猜測你的程序是處理大文件,你可能會長時間保存引用。

3

即使仍然有解決的,如果你仍然想老根在頻繁的小規模的暫停被清除,你可以嘗試設置

-XX:MaxGCPauseMillis=(time in millis) 

的主要問題(內存泄漏),這僅適用於帶有並行收集器和適應性調整策略處於打開狀態。默認情況下,「自適應調整大小策略」處於啓用狀態,但如果您想明確提及此信息,則可以使用。

-XX:+UseAdaptiveSizePolicy 

要不然你可以切換到CMS收集器,你可以使用

-XX:CMSInitiatingOccupancyFraction=(% value) 
-XX:+UseCMSInitiatingOccupancyOnly 

這是收集老根時,它已經達到了老根的某一部分的更可靠的方式。

+0

我嘗試了這些JVM參數,顯然GC不能釋放舊的gen空間,並且每次都能夠恢復幾乎沒有任何內存的情況下不斷釋放內存。 – amitsalyan 2014-09-19 16:31:56

+0

如果在完整的gc之後內存沒有被顯着恢復,那麼你的舊gen中就不是垃圾。在這種情況下,這可能是應用程序的內存佔用量。如果是這樣,你應該考慮增加分配的總內存。假設有狀態會話Bean是內存的主要佔用者,我會說內存足跡大約等於(創建新會話的速度*會話超時*會話的平均大小) – 2014-09-22 13:44:28

+0

爲什麼不分享堆的另一個分析做了優化之後(@Remove註釋)?所以我會更好地瞭解情況。我很想看到jmap -histo的輸出:live 2014-09-22 13:49:26