压测时,经常需要关注线程池的情况,所以增加这个命令来展示线程池关键信息。 输出参数如下: stackInfo:由于线程池没有名字,所以侧面通过execute方法调用栈信息来判断是那个业务线程池 corePoolSize:配置的核心线程数 maximumPoolSize:配置的最大线程数 activeThreadCount:当前繁忙线程数 currentSizeOfWorkQueue:当前队列堆积数
tomcat线程池:
dubbo线程池:
支持指令: threadpool -n :输出指定个数的线程池信息,优先按繁忙线程数排序,其次按队列堆积数排序,最后按最大线程数排序,默认输出全部线程池信息,如:threadpool -n 5 表示指定输出前5个 threadpool -sd : 输出指定深度的调用栈信息,当输出的栈信息无法判断是哪个业务线程池时,可以调大这个参数,负数表示输出全部调用栈信息,该调用栈指java.util.concurrent.ThreadPoolExecutor的execute方法调用栈,已经过滤了arthas增强类的调用栈信息,默认是2行,如:threadpool -sd 5 指定输出5行调用栈信息 threadpool -d:指令执行总时长(ms),记录指定毫秒数内触发过execute方法的线程池的信息,默认1000毫秒,在指定时间内会按照指定的频率(由threadpool -i指定,默认200ms)采集线程池的【当前繁忙线程数】和【队列堆积数】数据,最后输出平均值,threadpool -d 3000 表示采样总时长3000毫秒 threadpool -i:采样频率(ms),默认200ms,按指定频率采集线程池的【当前繁忙线程数】和【队列堆积数】数据,最后输出平均值,如:threadpool -i 200 采集频率是200ms
实现原理:增强java.util.concurrent.ThreadPoolExecutor类的execute方法,在有任务提交时,将线程池对象放入concurrentHashMap中(会先后两次通过无锁的get来判断是否已经加入到map中,只有不存在时才通过有锁的put加入map,减少性能影响),通过timer定时任务根据指定频率采集线程池信息,最后输出平均值
关注点:由于增强的是jvm自带的系统类,所以开启了GlobalOptions.isUnsafe标识,在命令结束后会关闭该标识