JVM優化--優化gc

什麼時候需要排查gc問題

我們遇到什麼樣的現象會懷疑gc有問題,進而優化呢?gc問題大體上可以分爲兩類:內存溢出、gc不健康。
內存溢出一般會藉助dump文件進行查看,設置jvm參數-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/applogs/system/error.dump可以在發生oom時給出dump信息。有了dump信息可以使用MAT,Jprofile,jvisualvm 進行排查。
gc不健康主要表現在這麼幾個方面:young gc頻繁或者不頻繁,理想頻率是5s一次,一次50ms以內。old gc理想頻率是一天一次。這個參數根據應用的重要性、tps等會有不同的要求。例如我司的大多數RPC接口要求50ms以內響應,白天不允許發生full gc(發生full gc會stop the world,造成接口響應時間變長,容易引發短時間內大量接口超時。)
總結一下,當遇到OOM報錯、服務有突刺、間歇性的超時等問題時,我們需要查看一下gc情況是否合理,即時調整。

gc不正常的原因

當發現gc情況跟我們上面說的指標不太一致時,可以嘗試用這幾個方面去分析原因。
young gc不正常原因一般是堆空間大小設置不合理,也有可能大對象直接進入老年代等。
old gc不正常可能原因有
1: Old 區內存不夠;
2:元數據區內存不夠;
3:System.gc();
4:jmap 或者 jcmd;
5:CMS Promotion failed 或者 concurrent mode failure;
6:JVM 基於悲觀策略認爲這次 YGC 後 Old 區無法容納晉升的對象,因此取消 YGC,提前 FGC。

排查思路

1.分析gc問題,我們首先需要知道配置的jvm參數,jdk版本等信息。然後分析jvm參數的合理性,有初步的方向。
2.通過查看堆內存信息,瞭解堆內存的使用情況。
3.如果有監控工具,可以觀察GC異常時間內,系統的調用情況。
4.結合GC日誌進行排查。

實戰演練

某應用最近進行重大升級,用戶訪問量擴大10倍,開發同事持續進行了兩個月高強度的開發終於上線了。上線後總體平穩,但出現了兩波超時。
當時沒太當回事,超時發生在1分鐘以內,且沒有持續超時。以爲是服務突刺、網絡問題等導致的,沒有跟蹤。
第二天又發生了一次,這引起了我們的重視,想到可能有gc問題。
通過觀察公司監控平臺,發現對應時間點發生了full gc(如果公司缺少這樣的監控平臺,通過分析gc日誌也能看出來,我們的垃圾回收器用的CMS+parnew,在gc日誌裏面搜索CMS可以看到full gc的情況,搜索GC (Allocation Failure))可以看到young gc的情況。young gc的情況一分鐘15次左右,耗時比較短。
檢查了一下JVM參數配置,指令是ps -ef|grep java 。由於我們的應用是部署在docker鏡像上,一個鏡像只部署了一個應用,這樣找出來的就是我們的應用JVM配置。
觀察到兩個問題,沒有設置元空間大小,老年代空間太小了,只有500M。
公司運維默認設置年輕代:老年代3:1,總共2G內存。調整爲元空間默認256M,最大512M,年輕代1228M,老年代800M。
調整後重新部署效果很好,基本不會產生full gc,年輕代的GC情況也還正常。

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