一、CPU飙升可能的原因
背景:CPU是整个电脑的核心计算资源,对于一个应用进程来说,CPU的最小执行单元是线程
导致CPU飙高的原因有几个方面:
- CPU上下文切换过多:由于在同一时刻下每个CPU核心只能运行一个线程,如果存在多个线程,CPU就只能通过上下文切换(上下文切换=保存运行线程的执行状态+执行处于等待中的线程)来执行不同的线程。在Java中,文件IO、网络IO、锁等待、线程阻塞等操作都会造成线程阻塞从而触发上下文切换
- CPU资源过度消耗:也就是在程序中创建了大量的线程,或者有线程一直占用CPU资源无法被释放。比如死循环
二、排查步骤
- 查找占用CPU高的进程PID:使用
top
命令查找,找到CPU高的进程PID - 查找进程中CPU高的线程TID:使用
ps -mp <PID> -o THREAD,tid,time
命令查找,找到CPU高的线程TID(这里打印的TID是十进制的,需要转为十六进制,可以通过命令printf "%x\n" <TID>
转换,如十进制3936对应十进制f60) - 查看占用资源异常的线程栈:使用
jstack <TID>
命令查看(简易的话可以用jstack <TID> | grep <十六进制TID> -A20
快速定位异常堆栈),就可以看到具体是哪一块代码出现了问题(一般是死循环、阻塞等)
如果定位的结果是程序正常,有可能是CPU飙升时,用户访问量较大,导致系统资源不够,可适当调整配置
//TODO 截图补充