ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

因Full GC导致CPU飙升到100%问题排查记录

2022-07-17 00:01:19  阅读:217  来源: 互联网

标签:Full 100% 线程 内存 进程 GC CPU


背景

提供了一个商品信息查询接口,此接口中会从Redis缓存中读取一个大对象列表出来,然后再根据传入的参数,对大对象列表进行过滤,进而得到最终的返回结果。

这里是一个比较典型的触发CPU飙高的场景,单次调用会生成大对象导致占用大量的年轻代空间。如果在业务高峰期,调用这个商品查询接口的频次很高的话,会导致堆内存飙升,老年代空间飙升,最终导致Full GC,如果不停地请求这个接口,会发现GC垃圾回收的时间会不停地加长,因为刚回收完,又产生了大量的对象放到了老年代中。如此反复导致了CPU居高不下。

原因

为什么垃圾回收时会占用大量的CPU资源,并引起CPU的波动,从理论上来说有以下原因: 

1) 垃圾回收的时候会暂时挂起所有线程,然后GC会检测扫描每一个线程栈上可回收对象,然后会移动对象,并且重新设置对象指针,这整个过程首先是消耗CPU的

2) 而且在这个过程之后恢复线程执行,这个时候CPU往往会引起一个高峰因为已经有更多的请求等待了

排查思路

不管什么问题,既然是CPU飙升,肯定是查一下耗CPU的线程,然后看看GC。

核心排查步骤

1.执行“top”命令:查看所有进程占系统CPU的排序。极大可能排第一个的就是咱们的java进程(COMMAND列)。PID那一列就是进程号。

2.执行“top -Hp 进程号”命令:查看java进程下的所有线程占CPU的情况。

3.执行“printf "%x\n 10"命令 :后续查看线程堆栈信息展示的都是十六进制,为了找到咱们的线程堆栈信息,咱们需要把线程号转成16进制。例如,printf "%x\n 10-》打印:a,那么在jstack中线程号就是0xa.

4.执行 “jstack 进程号 | grep 线程ID”  查找某进程下-》线程ID(jstack堆栈信息中的nid)=0xa的线程堆栈信息。如果“"VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable”,第一个双引号圈起来的就是线程名,如果是“VM Thread”这就是虚拟机GC回收线程了

5.执行“jstat -gcutil 进程号 统计间隔毫秒 统计次数(缺省代表一致统计)”,查看某进程GC持续变化情况,如果发现返回中FGC很大且一直增大-》确认Full GC!-》dump出内存,查找程序哪里内存溢出了。-》可明确看到gc的原因!

一般会引发CPU飙高的场景

1.内存消耗过大,导致Full GC次数过多

代码中某个位置读取数据量较大,导致系统内存耗尽,从而导致Full GC次数过多,系统缓慢; 

执行步骤1-5:

  • 多个线程的CPU都超过了100%,通过jstack命令可以看到这些线程主要是垃圾回收线程-》上一节步骤2
  • 通过jstat命令监控GC情况,可以看到Full GC次数非常多,并且次数在不断增加。--》上一节步骤5

确定是Full GC,接下来找到具体原因:

  • 生成大量的对象,导致内存溢出,此时可以通过eclipse的mat工具查看内存中有哪些对象比较多,MAT:Eclipse Memory Analyzer(MAT),内存泄漏插件,安装使用一条龙
  • 内存占用不高,但是Full GC次数还是比较多,此时可能是代码中手动调用 System.gc()导致GC次数过多,这可以通过添加 -XX:+DisableExplicitGC来禁用JVM对显示GC的响应。

2.代码中有大量消耗CPU的操作,导致CPU过高,系统运行缓慢;

执行步骤1-4:在步骤4jstack,可直接定位到代码行。例如某些复杂算法,甚至算法BUG,无限循环递归等等。

后记

之前写过两篇关于CPU飙高的问题分析,链接如下。

JVM调优之Java进程消耗CPU过高

因死循环导致CPU飙升到100%的问题排查记录

 

参考资料

https://copyfuture.com/blogs-details/20190925170715818fj1faa1vbc51fo0

https://blog.csdn.net/u010180738/article/details/124071109

https://blog.csdn.net/weixin_30888707/article/details/98596954

 

本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。

原文链接:https://www.cnblogs.com/lingyejun/p/16484045.html

标签:Full,100%,线程,内存,进程,GC,CPU
来源: https://www.cnblogs.com/lingyejun/p/16484045.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有