通過Java GC日志分析,幫助用戶從CMS GC升級到G1 GC,解決升級過程中的各種問題。
用戶訴求
某日接到業務同學的反饋如下:
業務運行過程中經常出現超長的暫停時 間,導致健康檢查失敗,引發問題。
應用本身是做離線數據處理,對時延要求不是很高,能保證大部分暫停在1200毫秒以下不要出現超長的暫停即可,更加看重應用的吞吐。
應用當前使用的是CMS GC,用戶希望順應技術發展趨勢,升級到G1 GC,并一并解決上述問題。
GC日志分析
首先看一下原本使用CMS時問題有多嚴重,文件上傳后先調整一下分析配置:
看問題診斷,發現有很多Full GC、Final Remark和Young GC的暫停時間都會超過1200ms。
再看一下暫停視圖,發現有時超時非常多。
用戶修改了JVM啟動參數,從CMS GC升級到G1 GC,運行了一段時間后重新上傳GC日志進行分析,看問題診斷,暫停信息和GC階段三個部分:
發現升級到G1 GC后可以看到應用的暫停時間基本滿足要求了,但是由于G1默認會試圖把應用暫停盡量控制在200ms以下,而當前應用的暫停整體偏長,導致G1試圖把年輕代壓縮得特別小來控制暫停時間,導致GC變得較為頻繁,引起應用整體的吞吐下降(應用吞吐主要看的是”GC暫停時間占比“指標,從2.38%升到了3.87%)。
為了降低Young GC的頻率增大年輕代大小,應用按照建議增加了以下JVM參數進行調優:
-XX:MaxGCPauseMillis=400 -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=40
運行一段時間后,發現雖然能解決GC頻繁的問題,但是由于年輕代大小的最小值被設的太高,影響了G1 GC自動調節能力,導致了新的Full GC和To-space Exhausted,引起超長暫停。
再次進行JVM參數調優:
-XX:G1NewSizePercent=20 -XX:-XX:InitiatingHeapOccupancyPercent=40
新的參數運行一段時間后沒有再發現新的問題,至此用戶G1 GC升級完成。用戶在Java GC日志分析工具的輔助下,通過JVM參數調優,在保持應用吞吐影響不大的情況下解決了時延問題,整體效果滿意。