组内应用频繁FullGC问题排查过程记录

背景:组内应用都配置了告警的项目,其中JVM的FullGC配置的是10s内连续FullGC两次即触发告警,近期观察到其中一个java web应用频发告警,打开监控平台后发现每天触发FullGC上千次,由于FullGC会导致STW,造成短时间内应用不可用,一定程度上会影响到用户的使用体验,因此决定排查一下频繁GC的原因。

排查过程:
1.首先查看JVM启动的参数配置,-Xms和-Xmx都是4G,垃圾收集器采用的是PS Scanvage和PS Marksweep,应用的总内存为8G。
从最初主机的运行参数可以简要排查出一些原因,由于FullGC如此频繁,因此原因可能有多个,几个常见触发FullGC的原因有:
(1)手动调用System.gc()
(2)堆内存空间不足
(3)永久代或元空间内存不足
(4)内存担保机制

观察主机其中一段时间内的运行情况,可以看出某些时间堆内存不足是其中的原因之一:
在这里插入图片描述

2.除了最简单从运行参数就能看出来的原因,其他原因就需要辅助其他手段,首先增加JVM参数:
-XX:+PrintGCDetails,该参数可以在GC时把相关的信息打印在控制台,根据日志可以进一步分析GC的原因与导致GC背后的代码逻辑。

加上该参数后,由于GC十分频繁,实时日志中的GC也不难找出,GC日志如下:
YoungGC:
在这里插入图片描述
YoungGC的原因为Allocation Failure,即内存分配失败,新生代内存空间已满导致的GC,其中箭头左右为GC前后的内存,前一个箭头代表年轻代的内存,后一个箭头代表总堆内存,可以看到发生YoungGC时年轻代的内存基本全被回收,而YoungGC时老年代中只有几百M的对象,相对比较空闲,考虑到当前年轻代与老年代的比例是1:2,即年轻代约1.3G,老年代约2.7G,因此可以适当调整一下分代的比例。

FullGC:
在这里插入图片描述
FullGC的原因非常令人不可思议。竟然是代码中手动触发的System.gc(),但是全局搜索代码后发现并没有发现有显式调用该方法的地方,因此可能是调用的三方依赖中调用了该方法,具体调用的位置还有待排查,由于基本所有的FullGC都没有与内存有直接关系,只是因为代码中的显式调用,因此先添加参数-XX:-DisableExplicitGC来禁用System.gc(),但JVM的GC仍然有效。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值