记一次内存暴涨频繁触发FULLGC导致的CPU资源耗尽

记一次内存暴涨频繁触发FULLGC导致的CPU资源耗尽

异常现象

线上服务突然卡死,进入服务器查看CPU资源耗尽,服务不能正常继续运行
top -Hp pid查看服务进程中的线程消耗情况
记一次内存暴涨频繁触发FULLGC导致的CPU资源耗尽

定位方法

上面已经看到四个线程将4核服务器资源消耗完
printf %x pid 得到线程的nid

使用jstack工具查看线程状况

jstack pid | grep nid-A 200
记一次内存暴涨频繁触发FULLGC导致的CPU资源耗尽
发现资源全部消耗在ParallelGC上,那么我们就要查看gc的详情信息

使用jstat gcutil工具

jstat -gcutil pid 刷新频率(毫秒)
记一次内存暴涨频繁触发FULLGC导致的CPU资源耗尽
此时eden区和old区都已经爆满,fullGC一次时间在3s左右

使用jmap查看heap存活对象

jmap -histo:live pid | head -20
记一次内存暴涨频繁触发FULLGC导致的CPU资源耗尽这里并不能直观看到本包对象,前面为byte[]和hashMap node消耗最多
需要借助一下分析工具了;常见就是jhat,jvisualvm,MAT(eclipse插件,不过现在idea使用居多,也有独立版)

DUMP分析

我这里使用jvisualvm查看一下引用
首先通过jmp快照获取dump文件
jmap -dump:format=b,file=文件名 pid
打开jvisualvm->文件->装入 导出的dump文件
记一次内存暴涨频繁触发FULLGC导致的CPU资源耗尽我这里主要关注到jmap查看到的ByteArrayRow对象,这里已经怀疑是存在select大量数据在内存没有及时释放,通过应用找到集合里面的字段内容定位到本项目的一个数据库,从代码逻辑理出对此项目库的查询操作
记一次内存暴涨频繁触发FULLGC导致的CPU资源耗尽
存在定时任务中循环单sql百万条数据的查询
至此基本找到了此次内存暴涨导致fullGC使CPU资源耗尽的问题

如有错误麻烦大佬们指正