首先,我们要清楚cpu飙高的原因:
cpu最小执行单位是线程,同一个是时刻下,一个核心只允许执行一个线程,如果有多个线程需要执行cpu只能通过切换上下文进行调度,cpu调度线程就需要记录线程的状态还有让等待中的线程执行,这会让cpu执行内核指令去实现状态的保存和恢复,占用cpu资源,线程中的锁等待、网络io、文件io等都会造成cpu上下文切换;
1、创建的线程过多导致cpu上下文频繁切换;
2、线程一直占有cpu无法被释放,可能是死循环;
排查方式:
1、先使用top命令查看系统资源是使用信息,top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况。我运行了个java进程模拟线上业务排查。
top
PID为7607的进程占用的CPU资源已接近100%。
2、接着使用命令查看该进程详细的线程情况
top -H -p 7607
上面显示线程的PID是十进制,我们需要转换成十六进制方便查找
(这里是同一个线程一直占用cpu资源,若是不同线程需要挑选几个去代码中排查是否正常)
3、转换线程PID
printf "%x\n" 7623
4、输出jstack 内容或转换成文件
我们可以直接线上使用jstack查看java中的线程信息,grep 1dc7是过滤出该线程信息,-A50是打印信息行数。
jstack 7607 | grep 1dc7 -A50
红框中就是我在程序中跑的线程名,所以我们使用线程要有良好的习惯,给线程加上名字,不过我们一般不会直接使用线程,而是使用线程池。现在找到了线程的名字我们就可以到java代码中全局搜索这个字符串定位到代码。
也可以把java进程中的线程信息输出到文本里进行查找,执行命令会输出到当前目录,jstack.log是文件名
jstack 7607 > jstack.log
把文件下载下来在搜索1dc7也会找到这个线程
5、 在idea中全局搜索用线程名定位java代码
以上就是排查步骤,当我们排查到原因后需要确认程序是否正常,如果不正常则修复代码,若是正常就要考虑是否资源不足,需要申请多点资源;