https://mp.weixin.qq.com/s/I1fp89Ib2Na1-vjmjSpsjQ

线上服务的FGC问题排查,看这篇就够了!

2020-05-10

线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力。同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验。

过去半年时间里,我们的广告系统出现了多次和GC相关的线上问题,有Full GC过于频繁的,有Young GC耗时过长的,这些问题带来的影响是:GC过程中的程序卡顿,进一步导致服务超时从而影响到广告收入。

这篇文章,我将以一个FGC频繁的线上案例作为引子,详细介绍下GC的排查过程,另外会结合GC的运行原理给出一份实践指南,希望对你有所帮助。内容分成以下3个部分:

  • 从一次FGC频繁的线上案例说起
  • GC的运行原理介绍
  • 排查FGC问题的实践指南

 

01 从一次FGC频繁的线上案例说起

去年10月份,我们的广告召回系统在程序上线后收到了FGC频繁的系统告警,通过下面的监控图可以看到:平均每35分钟就进行了一次FGC。而程序上线前,我们的FGC频次大概是2天一次。下面,详细介绍下该问题的排查过程。

FGC频繁 GC卡顿

 

 

 

1. 检查JVM配置通过以下命令查看JVM的启动参数:ps aux | grep "applicationName=adsearch"

-Xms4g -Xmx4g -Xmn2g -Xss1024K 

-XX:ParallelGCThreads=5 

-XX:+UseConcMarkSweepGC 

-XX:+UseParNewGC 

-XX:+UseCMSCompactAtFullCollection 

-XX:CMSInitiatingOccupancyFraction=80

可以看到堆内存为4G,新生代为2G,老年代也为2G,新生代采用ParNew收集器,老年代采用并发标记清除的CMS收集器,当老年代的内存占用率达到80%时会进行FGC。进一步通过 jmap -heap 7276 head -n20 可以得知新生代的Eden区为1.6G,S0和S1区均为0.2G。2. 观察老年代的内存变化

通过观察老年代的使用情况,可以看到:每次FGC后,内存都能回到500M左右,因此我们排除了内存泄漏的情况。

FGC频繁 GC卡顿

 

 

 3. 通过jmap命令查看堆内存中的对象

通过命令 jmap -histo 7276 | head -n20

相关文章: