这是我参与更文挑战的第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
。
如上图所示。当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的监控。
使用ManagementFactory
获取不同的MXBean
,以下为获取内容项的代码。
addRuntimeInfo(jvmModel)
获取当前 JVM 的信息,包括 JVM 参数和 JVM 相关的系统参数。
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean()
名称 | 代码 |
---|---|
MACHINE-NAME | runtimeMXBean.getName() |
JVM-START-TIME | runtimeMXBean.getStartTime() |
MANAGEMENT-SPEC-VERSION | runtimeMXBean.getManagementSpecVersion() |
SPEC-NAME | runtimeMXBean.getSpecName() |
SPEC-VENDOR | runtimeMXBean.getSpecVendor() |
SPEC-VERSION | runtimeMXBean.getSpecVersion() |
VM-NAME | runtimeMXBean.getVmName() |
VM-VENDOR | runtimeMXBean.getVmVendor() |
VM-VERSION | runtimeMXBean.getVmVersion() |
INPUT-ARGUMENTS | runtimeMXBean.getInputArguments() |
CLASS-PATH | runtimeMXBean.getClassPath() |
BOOT-CLASS-PATH | runtimeMXBean.getBootClassPath() 低于jdk9会报错不支持 |
LIBRARY-PATH | runtimeMXBean.getLibraryPath() |
addClassLoading(jvmModel)
获取 JVM 类加载情况。
ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean()
名称 | 代码 |
---|---|
LOADED-CLASS-COUNT | classLoadingMXBean.getLoadedClassCount() |
TOTAL-LOADED-CLASS-COUNT | classLoadingMXBean.getTotalLoadedClassCount() |
UNLOADED-CLASS-COUNT | classLoadingMXBean.getUnloadedClassCount() |
IS-VERBOSE | classLoadingMXBean.isVerbose() |
addCompilation(jvmModel)
获取 JVM 编译情况
CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean()
名称 | 代码 |
---|---|
NAME | compilationMXBean.getName() |
TOTAL-COMPILE-TIME | compilationMXBean.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()
名称 | 代码 |
---|---|
OS | operatingSystemMXBean.getName() |
ARCH | operatingSystemMXBean.getArch() |
PROCESSORS-COUNT | operatingSystemMXBean.getAvailableProcessors() |
LOAD-AVERAGE | operatingSystemMXBean.getSystemLoadAverage() |
VERSION | operatingSystemMXBean.getVersion() |
addThread(jvmModel)
获取 JVM 线程使用情况。
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean()
名称 | 代码 |
---|---|
COUNT | threadMXBean.getThreadCount() 线程数 |
DAEMON-COUNT | threadMXBean.getDaemonThreadCount()守护线程数 |
PEAK-COUNT | threadMXBean.getPeakThreadCount() 峰值线程数 |
STARTED-COUNT | threadMXBean.getTotalStartedThreadCount() 已启动的线程的总数 |
DEADLOCK-COUNT | getDeadlockedThreadsCount(threadMXBean) 死锁线程数 |
addFileDescriptor(jvmModel)
名称 | 代码 |
---|---|
MAX-FILE-DESCRIPTOR-COUNT | OperatingSystemMXBean.class.getDeclaredMethod(“getMaxFileDescriptorCount”) |
OPEN-FILE-DESCRIPTOR-COUNT | OperatingSystemMXBean.class.getDeclaredMethod(“getOpenFileDescriptorCount”) |