週期性Full GC的解決

                      週期性Full GC的解決

目錄

背景

原因

參數說明


背景


線上應用的垃圾收集出現定時Full GC的異常現象。
1) 每隔10小時觸發一次Full GC;
2) 每次Full GC持續時間約爲2~3秒;
3) 與環境無關,線上環境、測試環境都會出現此問題;
 

原因

1. 很多NIO框架,比如netty會有很多內存映射的代碼(memory map),而mmap的內存分配至不會在用Eden區或者old區的,是屬於堆外分配,因此,這些框架中會手動調用system.gc來回收mmap分配的空間。(system.gc觸發的是full gc,只有full gc時纔會回收mmap分配的內存)。

2. 因爲NIO框架頻繁的調用full gc 會嚴重影響性能,因此,有人加上了這個參數:-XX:+DisableExplicitGC ,用來禁止system.gc對gc的觸發。加上後system.gc()將不會觸發gc。

3. 但是,如果完全不允許手動調用gc,

* 使用了NIO或者NIO框架(Mina/Netty)
* 使用了DirectByteBuffer分配字節緩衝區
* 使用了MappedByteBuffer做內存映射

以上情況下的堆外內存又無法回收,所以,才提到了用ExplicitGCInvokesConcurrent參數來替代DisableExplicitGC。

 

參數說明

參數:-XX:ExplicitGCInvokesConcurrent
含義:
Enables invoking of concurrent GC by using the System.gc() request.
This option is disabled by default and can be enabled only together with the -XX:+UseConcMarkSweepGC option.
System.gc()是正常FULL GC,在STW打開此參數後,在做System.gc()時會做background模式CMS GC(-XX:+UseConcMarkSweepGC),即並行FULL GC,可提高FULL GC效率。也就是說System.gc()還是會觸發GC的,只不過不是觸發一個 完全stop-the-world的full GC,而是一次併發GC週期(注:一次併發週期其實就是在CMS下的一次gc,CMS只能用在full gc 中,所以,也是一次full gc 只不過效率比較高罷了)
默認值:


注意:該參數在允許systemGC且使用CMS GC時有效。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章