一次频繁gc的故障分析

生产上一次频繁gc的故障分析

事情是这样的,公司的微服务监控系统显示我所在项目的一个服务频繁掉线。接到这个消息后。
首先,我觉得可能是服务器oom内存溢出了。就去查看服务状态,发现服务heap正常,表现出来的效果是正常的,就像没有掉线过一样。
然后,直接去找运维,去生产上的容器中,查看服务器状态。

1,通过 jps 查到服务进程

jps

2,通过如下命令查看服务内存状态

jstat -gc pid

效果如下

S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
135168.0 131584.0 63200.0  0.0   257536.0 57943.6  5718016.0  2111288.4  124952.0 116668.8 15152.0 13708.0 912880 47662.680 1028  17732.733 65395.413

累计fgc达到1000多次。ygc达到90多万次。特么的,简直被震惊了。特么,一次fgc时间达到10多秒。这下微服务监控显示频繁掉线的原因就呼之欲出了。本服务fgc次数过多,时间过长,导致本服务不能发给nacos心跳,让nacos以为本服务已经掉线,然后就触发频繁掉线报警。

3,gc过多的原因

通过如下命令,查看服务内存信息

jmap -heap pid

效果如下

Attaching to process ID 9, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.181-b13

using thread-local object allocation.
Parallel GC with 103 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 6392119296 (6096.0MB)
   NewSize                  = 536870912 (512.0MB)
   MaxNewSize               = 536870912 (512.0MB)
   OldSize                  = 5855248384 (5584.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.tools.jmap.JMap.runTool(JMap.java:201)
        at sun.tools.jmap.JMap.main(JMap.java:130)
Caused by: java.lang.RuntimeException: unknown CollectedHeap type : class sun.jvm.hotspot.gc_interface.CollectedHeap
        at sun.jvm.hotspot.tools.HeapSummary.run(HeapSummary.java:144)
        at sun.jvm.hotspot.tools.Tool.startInternal(Tool.java:260)
        at sun.jvm.hotspot.tools.Tool.start(Tool.java:223)
        at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
        at sun.jvm.hotspot.tools.HeapSummary.main(HeapSummary.java:49)
        ... 6 more

可以看到最大heap为6g,而新生代只有512m。频繁gc的原因也很明显了,新生代过少,导致频繁ygc,而服务数据量又大,就导致很多数据到了老年代。老年代满了,又fgc,又因为老年代过大,导致fyc时间变的很长。

4,解决方式

改启动参数 如下

java -jar  -Xms6048M -Xmx6048M -Xmn3588M -XX:-UseAdaptiveSizePolicy  -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M -XX:SurvivorRatio=8  *.jar
上一篇:nested exception is com.sun.jersey.api.client.UniformInterfaceException


下一篇:浅谈类加载和双亲委派机制