背景
提供了一个商品信息查询接口,此接口中会从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

本文详细介绍了如何排查和解决Java应用程序中CPU占用过高的问题,主要涉及垃圾回收、内存溢出、FullGC频繁等场景。通过`top`、`jstack`和`jstat`等命令定位问题,结合MAT工具分析内存,以及禁用`System.gc()`调用来减少不必要的垃圾回收。同时,指出大量消耗CPU的操作也可能导致系统运行缓慢,需要检查代码中可能存在复杂算法或错误。文章提供了完整的排查步骤和相关工具的使用方法。
最低0.47元/天 解锁文章
2754

被折叠的 条评论
为什么被折叠?



