Arthas 应用诊断利器学习及使用(七) 系统命令thread,jvm

831 阅读3分钟

这是我参与更文挑战的第5天,活动详情查看: 更文挑战

本文内容基于arthas 3.5.1 版本,介绍系统命令thread,jvm的使用及实现。

一.thread命令

查看当前线程信息,查看线程的堆栈

参数名称参数缩写参数说明必填项
id线程id可选
--all显示所有线程信息可选
--top-n-threads-n指定最忙的前N个线程并打印堆栈可选
--include-blocking-thread-b找出当前阻塞其他线程的线程可选
--sample-interval-i指定cpu使用率统计的采样间隔,单位为毫秒,默认值为200可选
--state按线程状态过滤,不区分大小写,可选项:NEW, RUNNABLE, TIMED_WAITING, WAITING, BLOCKED, TERMINATED可选
--lockedMonitors找出线程信息中带有lockedMonitors标识的,默认为false,可直接用thread -b可选
--lockedSynchronizers找出线程信息中带有lockedSynchronizers标识的,默认为false可选

文件位于com.taobao.arthas.core.command.monitor200.ThreadCommand.java

image.png

如上图所示。当id参数存在时,执行processThread(process),查找指定id的thread信息。

ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean()获取线程信息

ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(new long[]{id}, lockedMonitors, lockedSynchronizers);lockedMonitors和lockedSynchronizers默认均为false。

当参数topNBusy不为null时,即执行thread -n的时候,执行processTopBusyThreads(process),查找最忙的前N个线程并打印堆栈。

threadSampler.sample获取所有线程采样信息并且按照时间排序,只要截取列表前n个就是thread -n的内容。

findMostBlockingThread为true,即执行thread -b的时候,进入分支执行processBlockingThread(process)找出当前阻塞其他线程的线程。

ThreadUtil.findMostBlockingLock()找出被阻塞的线程信息。

threadMXBean.dumpAllThreads(threadMXBean.isObjectMonitorUsageSupported(), threadMXBean.isSynchronizerUsageSupported())找出阻塞线程 isObjectMonitorUsageSupported()测试 Java 虚拟机是否支持使用对象监视器的监视。 isSynchronizerUsageSupported()测试 Java 虚拟机是否支持使用 可拥有同步器的监视。

最后,processAllThreads(process)获取所有线程,若有参数--state,则循环过滤出符合条件的线程。

ThreadSampler 线程的cpu取样器,用于统计线程的cpu使用情况。

通过java.lang.management.ThreadMXBean#getThreadCpuTime()sun.management.HotspotThreadMBean#getInternalThreadCpuTimes()获取所有线程的调用时间。 将第一次的结果保存在一个HashMap中。当通过pause(long mills)方法即Thread.sleep(mills)睡眠等待一段时间后,在ThreadCommand中默认睡眠等待时间为2000ms。再次统计线程的cpu时间,与之前第一次的cpu时间比较,线程CPU使用率 = 线程增量CPU时间 / 采样间隔时间 * 100%获得cpu使用率。

二.jvm命令

查看当前JVM信息

文件位于com.taobao.arthas.core.command.monitor200.JvmCommand.java

执行命令会打印出很多相关信息,通过JMX做jvm的监控。

image.png

使用ManagementFactory获取不同的MXBean,以下为获取内容项的代码。

addRuntimeInfo(jvmModel) 获取当前 JVM 的信息,包括 JVM 参数和 JVM 相关的系统参数。

RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean()

名称代码
MACHINE-NAMEruntimeMXBean.getName()
JVM-START-TIMEruntimeMXBean.getStartTime()
MANAGEMENT-SPEC-VERSIONruntimeMXBean.getManagementSpecVersion()
SPEC-NAMEruntimeMXBean.getSpecName()
SPEC-VENDORruntimeMXBean.getSpecVendor()
SPEC-VERSIONruntimeMXBean.getSpecVersion()
VM-NAMEruntimeMXBean.getVmName()
VM-VENDORruntimeMXBean.getVmVendor()
VM-VERSIONruntimeMXBean.getVmVersion()
INPUT-ARGUMENTSruntimeMXBean.getInputArguments()
CLASS-PATHruntimeMXBean.getClassPath()
BOOT-CLASS-PATHruntimeMXBean.getBootClassPath() 低于jdk9会报错不支持
LIBRARY-PATHruntimeMXBean.getLibraryPath()

addClassLoading(jvmModel) 获取 JVM 类加载情况。 ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean()

名称代码
LOADED-CLASS-COUNTclassLoadingMXBean.getLoadedClassCount()
TOTAL-LOADED-CLASS-COUNTclassLoadingMXBean.getTotalLoadedClassCount()
UNLOADED-CLASS-COUNTclassLoadingMXBean.getUnloadedClassCount()
IS-VERBOSEclassLoadingMXBean.isVerbose()

addCompilation(jvmModel) 获取 JVM 编译情况 CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean()

名称代码
NAMEcompilationMXBean.getName()
TOTAL-COMPILE-TIMEcompilationMXBean.getTotalCompilationTime() 单位ms

addGarbageCollectors(jvmModel) 获取 JVM 垃圾收集器的情况。

Collection<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans()

addMemoryManagers(jvmModel)

Collection<MemoryManagerMXBean> memoryManagerMXBeans = ManagementFactory.getMemoryManagerMXBeans()

addMemory(jvmModel)获取当前 JVM 的内存使用,包括堆内存和非堆内存。

MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean()

addOperatingSystem(jvmModel)获取操作系统相关的信息

OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean()

名称代码
OSoperatingSystemMXBean.getName()
ARCHoperatingSystemMXBean.getArch()
PROCESSORS-COUNToperatingSystemMXBean.getAvailableProcessors()
LOAD-AVERAGEoperatingSystemMXBean.getSystemLoadAverage()
VERSIONoperatingSystemMXBean.getVersion()

addThread(jvmModel) 获取 JVM 线程使用情况。

ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean()

名称代码
COUNTthreadMXBean.getThreadCount() 线程数
DAEMON-COUNTthreadMXBean.getDaemonThreadCount()守护线程数
PEAK-COUNTthreadMXBean.getPeakThreadCount() 峰值线程数
STARTED-COUNTthreadMXBean.getTotalStartedThreadCount() 已启动的线程的总数
DEADLOCK-COUNTgetDeadlockedThreadsCount(threadMXBean) 死锁线程数

addFileDescriptor(jvmModel)

名称代码
MAX-FILE-DESCRIPTOR-COUNTOperatingSystemMXBean.class.getDeclaredMethod("getMaxFileDescriptorCount")
OPEN-FILE-DESCRIPTOR-COUNTOperatingSystemMXBean.class.getDeclaredMethod("getOpenFileDescriptorCount")