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

本文详细介绍了如何排查和解决Java应用程序中CPU占用过高的问题,主要涉及垃圾回收、内存溢出、FullGC频繁等场景。通过`top`、`jstack`和`jstat`等命令定位问题,结合MAT工具分析内存,以及禁用`System.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进制。例如,pr

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值