一、使用场景
当一个java应用CPU的使用比较高或者到达100%以上的时候,需要分析代码哪里有问题。这时候可以使用jstack命令
二、怎么使用
先使用命令ps –ef |grep keyword 找到应用的进程号,用PID表示。
然后使用命令导出当前的堆栈,命令如下
jstack 23000 > 1.log (23000为进程号,重定向到1.log文件)
查找cpu使用率最高的线程号,一个进程中有很多的线程(23000为进程号)
使用命令:
ps -mp 23000 -o THREAD,tid
得到如下结果:
USER %CPU PRI SCNT WCHAN USER SYSTEM TID
app 2.0 19 - n_tty_ - - 24876
app 2.0 19 - futex_ - - 24879
app 1.9 19 - futex_ - - 24882
app 1.9 19 - futex_ - - 24885
app 1.9 19 - futex_ - - 24888
app 0.0 19 - futex_ - - 24916
app 97.3 19 - - - - 24917
app 0.0 19 - futex_ - - 24918
app 0.0 19 - futex_ - - 24919
app 0.0 19 - futex_ - - 24920
app 0.0 19 - futex_ - - 24921
发现24917的线程使用率为97.3
使用linux命令行工具
printf '%x' 24917
将10进制的24917转化为16进制的6155,因为堆栈中的线程号都是用十六进制表示。
vi 1.log进入堆栈日志搜索/6155结果如下
"changeService" prio=10 tid=0x00007f5158101000 nid=0x6155 runnable [0x00007f4f92dec000]
java.lang.Thread.State: RUNNABLE
at com.xxx.service.impl.ChangeServiceImpl.execute(ChangeServiceImpl.java:115)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
发现这里的代码可能有问题,通过定位,发现这边写了个死循环导致系统cpu使用率飙高。