生产环境GC故障解决过程记录
生产环境GC故障解决过程记录
陈小扁 发表于8个月前
生产环境GC故障解决过程记录
  • 发表于 8个月前
  • 阅读 21
  • 收藏 4
  • 点赞 2
  • 评论 1

腾讯云 新注册用户 域名抢购1元起>>>   

摘要: 1.背景说明 2.解决过程 3.总结

排查了五六个小时,终于解决了GC的问题,记录一下希望可以帮到有需要的人,本文假定读者对GC知识有一定的了解 如果不了解可以先参考我的博客 https://my.oschina.net/chenxiaobian/blog/726840

1.背景说明

发生的问题是公司一台跑linux服务器上的应用,下午接到通知说整个服务挂了,于是登上服务器一看状态 发现服务是启动的,但是访问应用确实是没任何响应,于是通过命令top查看了一下cpu的运行状态,发现一个叫jetty的进程占用cpu 比例为100%,初步一看肯定是内存泄漏了

 

2.解决过程

于是通过命令查看一下JVM的配置参数

ps -ef|grep jetty|grep -v grep

查到

 -Xmx1536m -Xms1536m -Xmn576m -Xss512K -XX:PermSize=384m -XX:MaxPermSize=384m 

可以看到持久代被设置为384M,堆内存被设置为1536M(-Xms和--Xmx设为相等避免了“堆震荡”,能在一定程度减少GC次数,但会增加平均每次GC消耗的时间),年轻代被设置为576M

接下来分别一一进行排查

通过top命令可以查到占用内存最大的进程号

通过执行命令

jstat -gc 28048 250 4;//每250ms执行一次,一共4次

看了下堆中各代的占用情况和GC情况,发现了一个挺恐怖的现象:Eden区占用77%多,S0占用100%,Old和Perm区都有很大空间剩余

怀疑是新生代空间不足,但是没有确切证据,只好用jstack获取线程Dump信息 执行

jstack -F 28048

不看不知道,一看就发现了一个问题(没有发现线程死锁,这里应该是“活锁”问题)

从上面第一段可看到有一个Low Memory Detector系统内部线程(JVM启动的监测和报告低内存的守护线程)一直占着锁0x00....00,而下面的C2 CompilerThread1、C2 CompilerThread0、Signal Dispatcher和Surrogate Locker线程都在等待这个锁,导致整个JVM进程都hang住了

于是打算调大整个堆内存大小、调大新生代大小(-Xmn参数)、调大新生代中Survivor区占的比例(-XX:SurvivorRatio)

  重启系统后用jstat -gcutil pid 1000命令发现一个更恐怖的现象,如下图:Eden区内存持续快速增长,Survivor占用依然很高,大概每两分钟就Young GC一次,并且每次Young GC后年老代内存占用都会增加不少,这样导致可以预测每三四个小时就会发生一次Full GC,这是很不合理的

于是我用

jmap -histo:live

(注意jmap命令会触发Full GC,并发访问量较大的线上环境慎用)查看了下活对象,发现有一些Integer数组和一些Character数组占用内存在持续增长,并且占了大概好几百M的内存,然后经过Young GC又下降,然后再次快速增长,再Young GC下降,周而复始

 至此,我推测可能是大量的Integer数组对象和Character数组对象基本占满了Survivor,导致在Eden满了之后,新产生的Integer数组对象和Character数组对象不足以放入Survivor,然后对象被直接被Promote到了年老代,这种推测部分正确,它解释了S1占用那么高的原因,但不能解释上面的Eden区内存占用持续上升。

于是继续查看了下接口调用日志,不看不知道,一看吓一跳:日志刷新非常之快(99%是ERROR日志,原因就在于大量的系统接口调用触发了大量ERROR和DEBUG日志刷新,写日志对于线上系统是一个重量级操作,无论是对CPU占用还是对内存占用,所以高并发线上系统一定要记得调高日志级别为INFO甚至ERROR

 

于是通过jmap命令

jmap -dump:format=b,file=/tmp/dump.dat 20248 

把文件dump下来通过heap analyzer打开分析发现是一个叫automsphere占用堆栈空间达92%以上,通过工具把dump.dat文件打开进行分析排查

 

通过后台ERROR日志发现一直在建立socketConnetion 连接,所以通过这里猜测肯定是程序中有问题,通过排查发现程序会有一个聊天功能需要用到automsphere

 

3.总结

需要说明一下,本文当中很多截图并不是当时现场的图,因为时间紧迫没来得及截图,本文是对这次事故的一次总结,推荐几篇不错的GC方面的文章

   JVM内存管理:深入Java内存区域与OOM http://www.iteye.com/topic/802573

   JVM内存管理:深入垃圾收集器与内存分配策略 http://www.iteye.com/topic/802638

   GC实践总结 http://www.iteye.com/topic/473874

   JVM内存的分配及回收 http://blog.csdn.net/eric_sunah/article/details/7893310

   一步一步优化JVM系列 http://blog.csdn.net/zhoutao198712/article/category/1194642

 

 

标签: gc机制
共有 人打赏支持
粉丝 44
博文 87
码字总数 70089
评论 (1)
ch751652064
收藏了:smile:
×
陈小扁
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: