jvm排查線上gc問題步驟

1. 清楚從程序角度,有哪些原因導致FGC? 

  • 大對象:系統一次性加載了過多數據到內存中(比如SQL查詢未做分頁),導致大對象進入了老年代。

  • 內存泄漏:頻繁創建了大量對象,但是無法被回收(比如IO對象使用完後未調用close方法釋放資源),先引發FGC,最後導致OOM.

  • 程序頻繁生成一些長生命週期的對象,當這些對象的存活年齡超過分代年齡時便會進入老年代,最後引發FGC. (即本文中的案例)

  • 程序BUG導致動態生成了很多新類,使得 Metaspace 不斷被佔用,先引發FGC,最後導致OOM.

  • 代碼中顯式調用了gc方法,包括自己的代碼甚至框架中的代碼。

  • JVM參數設置問題:包括總內存大小、新生代和老年代的大小、Eden區和S區的大小、元空間大小、垃圾回收算法等等。

 

2. 清楚排查問題時能使用哪些工具

  • 公司的監控系統:大部分公司都會有,可全方位監控JVM的各項指標。

  • JDK的自帶工具,包括jmap、jstat等常用命令:

    # 查看堆內存各區域的使用率以及GC情況

    jstat -gcutil -h20 pid 1000

    # 查看堆內存中的存活對象,並按空間排序

    jmap -histo pid | head -n20

    # dump堆內存文件

    jmap -dump:format=b,file=heap pid (會停掉程序,謹慎使用)

  • 可視化的堆內存分析工具:JVisualVM、MAT等

 

3. 排查指南

  • 查看監控,以瞭解出現問題的時間點以及當前FGC的頻率(可對比正常情況看頻率是否正常)

  • 瞭解該時間點之前有沒有程序上線、基礎組件升級等情況。

  • 瞭解JVM的參數設置,包括:堆空間各個區域的大小設置,新生代和老年代分別採用了哪些垃圾收集器,然後分析JVM參數設置是否合理。

  • 再對步驟1中列出的可能原因做排除法,其中元空間被打滿、內存泄漏、代碼顯式調用gc方法比較容易排查。

  • 針對大對象或者長生命週期對象導致的FGC,可通過 jmap -histo 命令並結合dump堆內存文件作進一步分析,需要先定位到可疑對象。

  • 通過可疑對象定位到具體代碼再次分析,這時候要結合GC原理和JVM參數設置,弄清楚可疑對象是否滿足了進入到老年代的條件才能下結論

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