线上排查问题神器-Arthas应用(二)-thread命令

550 阅读2分钟

「这是我参与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

image

从线程的详情可以分析出,目前第一个线程的使用率是最高的,cpu占用了达到99.38%。第二行告诉我们,是Arthas.java这个类的第38行导致的。

由此,我们可以一眼看出问题,然后定位问题代码的位置,接下来就是人工排查问题了。

2、查询出当前被阻塞的线程

命令:

thread -b

image

可以看到内容提示,线程Thread-1被线程Thread-0阻塞。对应的代码行数是DeadLockTest.java类的第31行。根据这个提示去查找代码问题。

3、指定采样的时间间隔

命令

thread -i 1000

这个的含义是个1s统计一次采样