一个应用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果然没有再被拉高。