如何快速定位JVM中消耗CPU最多的线程?
在日常 Java 的开发中,性能调优肯定是很多人不能绕开的一个环节。而其中最简单,也是最基础的一个问题就是如何定位消耗 CPU 最多的线程。这篇文章中你假笨以一个简单的 Test 例子为蓝本,给各位总结了分析这类问题的常用『套路』。
具体如下。
这个例子里新创建了 11 个线程,其中 10 个线程没干什么事,主要是 sleep,另外有一个线程在循环里一直跑着,可以想象这个线程是这个进程里最耗 CPU 的线程了,那怎么把这个线程给抓出来呢?
首先我们可以通过top -Hp <pid>
来看这个进程里所有线程的 CPU 消耗情况,得到类似下面的数据。
拿到这个结果之后,我们可以看到 cpu 最高的线程是 pid 为 18250 的线程,占了 99.8%:
接着我们可以通过 jstack的输出来看各个线程栈:
上面的线程栈我们注意到 nid 的值其实就是线程 ID,它是十六进制的,我们将消耗 CPU 最高的线程18250
,转成十六进制0X47A
,然后从上面的线程栈里找到nid=0X47A
的线程,其栈为:
"Busiest Thread" #28 prio=5 os_prio=0 tid=0x00007fb91498d000 nid=0x474a runnable [0x00007fb9065fe000] java.lang.Thread.State: RUNNABLE at Test$2.run(Test.java:18)
最后,强烈推荐你假笨的微信公众号,他这几年写了很多 JVM 的文章,也做了很多方便我们调试的小工具,相信能帮到你,特别是想深入研究 JVM 的同学。同时,他公众号还记录了自己成为 JVM 专家的点滴历程,比如我是如何走时 JVM 这条贼船这篇文章,看完之后,给我以前进的力量。