一次FullGC 血案侦破过程

本文详细记录了一次由于FullGC导致的系统告警问题的排查过程,从检查系统负载、分析JVM日志到调整Tomcat内存配置,并最终发现并禁止显性调用System.gc(),成功解决了频繁FullGC的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、持续报警

恢复

2、查后台日志

top

jstat -gc pid

jstat -gc()capacity -pid

 

查看head(关于Java Dump日志重点关注点,见这篇文章《三个实例分析Java Thread Dump日志》

jstack pid

这种信息量太大且杂乱,不易定位问题点,加grep 搜索关键词 waiting on 定位下

 

3、峰回路转,问题出在这儿

    经过上述一顿查找、分析,似乎也没发现大的嫌疑点,内存、CPU占比并不高,也没有报OOM异常,问题出在哪儿呢?

 

回过头来,我们看告警值是8,这个8是怎么来的呢?这就与load average与CPU个数有关了。

系统平均负载(load average)被定义为在特定时间间隔内运行队列中的平均进程树。如果一个进程满足以下条件则其就会位于运行队列中:

(通俗的说,运行队列中的进程树正在消耗内存和CPU资源,从而能算出消耗资源的比例。)

         - 它没有在等待I/O操作的结果

  - 它没有主动进入等待状态(也就是没有调用'wait')

  - 没有被停止(例如:等待终止)

  例如:

  [root@opendigest root]# uptime

  7:51pm up 2 days, 5:43, 2 users, load average: 8.13, 5.90, 4.94

  命令输出的最后内容表示在过去的1、5、15分钟内运行队列中的平均进程数量。

而告警是指“每CPU活动进程数量”,= 总进程数量/CPU数量

一般来说只要每个CPU的当前活动进程数不大于3那么系统的性能就是良好的,如果每个CPU的任务数大于5,那么就表示这台机器的性能有严重问题。对于上面的例子来说,假设系统有两个CPU,那么其每个CPU的当前任务数为:8.13/2=4.065。这表示该系统的性能是可以接受的。

 

除此外,还要了解下谁触发了FullGC:(1)程序调用System.gc时可以触发;(2)系统自身来决定GC触发的时机。系统判断GC触发的依据:根据Eden区和From Space区的内存大小来决定。当内存大小不足时,则会启动GC线程并停止应用线程。

猛然想起,迁移到新环境,tomcat都是按默认的配置,是不是设置的内存太小呢?立即行动,在tomcat/bin/catalina.sh修改内存配置参数:

JAVA_OPTS="-server -Xms4g -Xmx4g -Xmn2500m -verbose:gc -Xloggc:/opt/gc_%p.log -XX:+PrintGCDetails

如何理解上述这段配置,借用《深入理解虚拟机》来看看:

JVM 中最大堆大小有三方面限制: 1.相关操作系统的数据模型(32-bt还是64-bit)限制; 2.系统的可用虚拟内存限制; 3.系统的可用物理内存限制. 在32位系统下,一般限制在1.5G~2G;64为操作系统对内存无特定限制.  

机器配置:8G内存   4核CPU

典型设置: 
java -Xmx4g -Xms4 -Xmn2500m -Xss256m
   -Xmx4g:设置JVM最大可用内存为4g.
   -Xms4g:设置JVM促使内存为4g.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存.
   -Xmn2g:设置年轻代大小为4G.

整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8

设置完重启tomcat,立马见效。告警消失了一大半,但还是有在报的,这是什么原因呢?既然硬件方面的原因解决,那肯定就出在代码上了。

 

cat pid.log |grep "System.gc()"

果然查出一大堆显性调用System.gc的代码,

看来运维小哥还得加油呀。于是在tomcat的catalina.sh加上将system.gc调用的禁用限制:-XX:+DisableExplicitGC

 

重启运行一段时间后,再也没报FullGC的告警了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值