「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」
thread命令查询CPU使用率最高的线程及问题原因
通过dashboard我们可以看到当前进程下运行的所有的线程。那么如果想要具体查看某一个线程的运行情况,可以使用thread命令
1. 统计cpu使用率最高的n个线程
先来看看常用的参数。
参数说明
| 参数名称 | 参数说明 |
|---|---|
| id | 线程id |
| [n:] | 指定最忙的前N个线程并打印堆栈 |
| [b] | 找出当前阻塞其他线程的线程 |
[i <value>] | 指定cpu使用率统计的采样间隔,单位为毫秒,默认值为200 |
| [--all] | 显示所有匹配的线程 |
我们的目标是想要找出CPU使用率最高的n个线程。那么需要先明确,如何计算出CPU使用率,然后才能找到最高的。计算规则如下:
首先、第一次采样,获取所有线程的CPU时间(调用的是java.lang.management.ThreadMXBean#getThreadCpuTime()及sun.management.HotspotThreadMBean.getInternalThreadCpuTimes()接口)
然后、睡眠等待一个间隔时间(默认为200ms,可以通过-i指定间隔时间)
再次、第二次采样,获取所有线程的CPU时间,对比两次采样数据,计算出每个线程的增量CPU时间
线程CPU使用率 = 线程增量CPU时间 / 采样间隔时间 * 100%
注意: 这个统计也会产生一定的开销(JDK这个接口本身开销比较大),因此会看到as的线程占用一定的百分比,为了降低统计自身的开销带来的影响,可以把采样间隔拉长一些,比如5000毫秒。
统计1秒内cpu使用率最高的n个线程:
thread -n 3 -i 1000
从线程的详情可以分析出,目前第一个线程的使用率是最高的,cpu占用了达到99.38%。第二行告诉我们,是Arthas.java这个类的第38行导致的。
由此,我们可以一眼看出问题,然后定位问题代码的位置,接下来就是人工排查问题了。
2、查询出当前被阻塞的线程
命令:
thread -b
可以看到内容提示,线程Thread-1被线程Thread-0阻塞。对应的代码行数是DeadLockTest.java类的第31行。根据这个提示去查找代码问题。
3、指定采样的时间间隔
命令
thread -i 1000
这个的含义是个1s统计一次采样