1.先用top命令,找到cpu占用最高的进程PID。
[test@e05dd99f6125 ~]# top
top - 08:26:15 up 11 days, 13:16, 0 users, load average: 0.80, 0.29, 0.18
Tasks: 3 total, 2 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 11.1 us, 5.6 sy, 0.0 ni, 83.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 2038544 total, 1160448 free, 321380 used, 556716 buff/cache
KiB Swap: 1048572 total, 1048572 free, 0 used. 1585692 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
514 test 20 0 11900 2708 2328 R 100.0 0.1 1:32.86 sh
1 test 20 0 12168 3308 2528 S 0.0 0.2 0:00.56 bash
537 test 20 0 56260 3900 3296 R 0.0 0.2 0:00.00 top
可以看到514进程,占用cpu100%。
2.再用下面命令查询进程中,那个线程的cpu占用率高,记录TID。
ps -mp pid -o THREAD,tid,time | sort -rn
[test@e05dd99f6125 ~]# ps -mp 514 -o THREAD,tid,time|sort -rn
test 99.5 19 - - - - 514 00:00:36
test 99.5 - - - - - - 00:00:36
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME
可以看到tid为514线程,使用cpu最高。这边只有单线程的一个程序,为了看排查流程。
3.将查找到的线程占用最高的 tid 转成16进制。
printf "%x\n" tid
[test@e05dd99f6125 ~]# printf "%x\n" 514
202
4.通过jstack命令获取占用资源异常的线程栈。
jstack pid > jstack.pid.log,可暂时保存到一个文件中查看。
或者
jstack pid |grep tid -A 30(tid为上面记录的TID的16进制)命令行查看。
jstack pid > jstack.pid.log #先保存文件,再从文件中查看
或者
jstack 514 |grep 202 -A 30 #直接命令行查看
5.从上面日志文件或者命令行查看日志,从日志中能看到自己编写的代码的类和方法。一般情况是对应代码处产生了死循环。 注:我这边是启用了一个docker,用shell写了一个简单的循环,只是为了记录排查的过程。