一个应用cpu利用率过高,若不是真的有大规模的密集型计算,基本就是出现了死循环!下面将以实际应用为例,介绍如何一步步排查这类问题。

1 通过top命令找到高cpu的进程

从上面命令可以看出,进程号为24707的java应用cpu占用率较高,达到了397.9%。

另外还可以通过ps aux | grep PID或者ps -ef| grep PID查看进程的详细信息。

2 用ps -mp PID -o THREAD,tid,time查看线程列表及cpu占用情况

从结果可以看出,线程号为24722-24731的程序cpu占用了大量cpu。

3 用printf “%x\n” num将上一步中需要的线程ID转换为16进制

4 用jstack 24707 |grep 6092 -A 10打印线程的堆栈信息

从堆栈信息可以看出,问题出现在ContentReader的第47行

5 查看代码ContentReader的第47行,果然有循环。。。。。

仔细看了下这段代码是用多个线程读取url的内容,当所有请求返回了再做下一步处理,简单看代码并没有问题,但如果某个线程返回较慢时,while循环将一直进行,此时cpu将被占满,要是再有其他类似线程,后果可想而知。。。。。

6 问题修复。只要找到问题原因修复就很简单了,把上述逻辑改为使用CompletionService即可,修改完再次上线,cpu果然没有再被拉高。