GC 持續時間 Garbage Collection 上的平均時間是每分鍾 5 分鍾。 警告閾值:30.00%。
原因 垃圾回收時間超過系統設置的時間閾值,
這就需要了解下什么時候觸發GC ,為什么會GC
Young GC----針對年輕代
當Eden區滿了的時候,會觸發Young GC
Full GC----針對整個堆
1. 在發生Young GC的時候,虛擬機會檢測之前每次晉升到老年代的平均大小是否大於年老代的剩余空間,如果大於,則直接進行Full GC;
2. 如果小於,但設置了Handle PromotionFailure,那么也會執行Full GC。promotion failed是在進行Minor GC時,survivor space放不下、對象只能放入老年代,而此時老年代也放不下造成的。
3. 永久代空間不足,會觸發Full GC
4. System.gc()也會觸發Full GC
5. 堆中分配很大的對象
所謂大對象,是指需要大量連續內存空間的java對象,例如很長的數組,此種對象會直接進入老年代,而老年代雖然有很大的剩余空間,但是無法找到足夠大的連續空間來分配給當前對象,此種情況就會觸發JVM進行Full GC。為了解決這個問題,CMS垃圾收集器提供了一個可配置的參數,即-XX:+UseCMSCompactAtFullCollection開關參數,用於在“享受”完Full GC服務之后額外免費贈送一個碎片整理的過程,內存整理的過程無法並發的,空間碎片問題沒有了,但提頓時間不得不變長了,JVM設計者們還提供了另外一個參數 -XX:CMSFullGCsBeforeCompaction,這個參數用於設置在執行多少次不壓縮的Full GC后,跟着來一次帶壓縮的。
6. CMS GC concurrent mode failure
concurrent mode failure是在執行CMS GC的過程中同時有對象要放入老年代,而此時老年代空間不足造成的(有時候“空間不足”是CMS GC時當前的浮動垃圾過多導致暫時性的空間不足觸發Full GC)。
簡單理解: 當 survivor space放不下時,會放到老年代里, 當老年代也放不下時就觸發了 full GC
解決辦法
full GC的根本原因是內存不足,導致老年代沒有足夠的內存接收對象,最簡單的辦法是加大JAVA 堆內存,
其次是優化 JVM
參考案例
通用法則1:
將java堆的初始值-Xms和最大值-Xmx設置為老年代活躍數據大小的3~4倍
所以此處就設置 -Xms1600m,-Xmx1600m
在以上的測試結果中可以看到原始的堆大小為1675m左右,是比較接近的。
通用法則2:
永久帶的初始值-XX:PermSize及最大值-XX:MaxPermSize應該比永久代活躍數據大1.2~1.5倍
所以此處就設置-XX:PermSize=13m,-XX:MaxPermSize=13m
補充法則:
新生代空間應該為老年代空間活躍數據的1~1.5倍
此處老年代為400m,新生代就為600m
如果java堆的初始值及最大值為活躍數據的3~4倍,新生代為活躍數據的1~1.5倍時,老年代應設置為活躍數據大小的2~3倍
參考表