dashboard
显示当前系统的实时数据面板,按q或ctrl+c退出
参数名称 | 参数说明 |
---|---|
[i:] | 刷新实时数据的时间间隔 (ms),默认 5000ms |
[n:] | 刷新实时数据的次数 |
数据说明:
- ID: Java 级别的线程 ID,注意这个 ID 不能跟 jstack 中的 nativeID 一一对应。
- NAME: 线程名
- GROUP: 线程组名
- PRIORITY: 线程优先级, 1~10 之间的数字,越大表示优先级越高
- STATE: 线程的状态
- CPU%: 线程的 cpu 使用率。比如采样间隔 1000ms,某个线程的增量 cpu 时间为 100ms,则 cpu 使用率=100/1000=10%
- DELTA_TIME: 上次采样之后线程运行增量 CPU 时间,数据格式为
秒
- TIME: 线程运行总 CPU 时间,数据格式为
分:秒
- INTERRUPTED: 线程当前的中断位状态
- DAEMON: 是否是 daemon 线程
JVM 内部线程:
Java 8 之后支持获取 JVM 内部线程 CPU 时间,这些线程只有名称和 CPU 时间,没有 ID 及状态等信息(显示 ID 为-1)。 通过内部线程可以观测到 JVM 活动,如 GC、JIT 编译等占用 CPU 情况,方便了解 JVM 整体运行状况。
- 当 JVM 堆(heap)/元数据(metaspace)空间不足或 OOM 时,可以看到 GC 线程的 CPU 占用率明显高于其他的线程。
- 当执行
trace/watch/tt/redefine
等命令后,可以看到 JIT 线程活动变得更频繁。因为 JVM 热更新 class 字节码时清除了此 class 相关的 JIT 编译结果,需要重新编译。
JVM 内部线程包括下面几种:
- JIT 编译线程: 如
C1 CompilerThread0
,C2 CompilerThread0
- GC 线程: 如
GC Thread0
,G1 Young RemSet Sampling
- 其它内部线程: 如
VM Periodic Task Thread
,VM Thread
,Service Thread
thread
查看当前线程信息,查看线程的堆栈
参数说明:
参数名称 | 参数说明 |
---|---|
id | 线程 id |
[n:] | 指定最忙的前 N 个线程并打印堆栈 |
[b] | 找出当前阻塞其他线程的线程 |
[i <value> ] |
指定 cpu 使用率统计的采样间隔,单位为毫秒,默认值为 200 |
[--all] | 显示所有匹配的线程 |
cpu 使用率是如何统计出来的?
这里的 cpu 使用率与 linux 命令top -H -p <pid>
的线程%CPU
类似,一段采样间隔时间内,当前 JVM 里各个线程的增量 cpu 时间与采样间隔时间的比例。
工作原理说明:
- 首先第一次采样,获取所有线程的 CPU 时间(调用的是
java.lang.management.ThreadMXBean#getThreadCpuTime()
及sun.management.HotspotThreadMBean.getInternalThreadCpuTimes()
接口) - 然后睡眠等待一个间隔时间(默认为 200ms,可以通过
-i
指定间隔时间) - 再次第二次采样,获取所有线程的 CPU 时间,对比两次采样数据,计算出每个线程的增量 CPU 时间
- 线程 CPU 使用率 = 线程增量 CPU 时间 / 采样间隔时间 * 100%
注意: 这个统计也会产生一定的开销(JDK 这个接口本身开销比较大),因此会看到 as 的线程占用一定的百分比,为了降低统计自身的开销带来的影响,可以把采样间隔拉长一些,比如 5000 毫秒。
使用参考
1.支持一键展示当前最忙的前 N 个线程并打印堆栈:
thread -n 3
- 没有线程 ID,包含
[Internal]
表示为 JVM 内部线程,参考dashboard命令的介绍。 cpuUsage
为采样间隔时间内线程的 CPU 使用率,与dashboard命令的数据一致。deltaTime
为采样间隔时间内线程的增量 CPU 时间,小于 1ms 时被取整显示为 0ms。time
线程运行总 CPU 时间。
注意:线程栈为第二采样结束时获取,不能表明采样间隔时间内该线程都是在处理相同的任务。建议间隔时间不要太长,可能间隔时间越大越不准确。 可以根据具体情况尝试指定不同的间隔时间,观察输出结果。
2.当没有参数时,显示第一页线程的信息
默认按照 CPU 增量时间降序排列,只显示第一页数据。
3.thread --all, 显示所有匹配的线程
4.thread id, 显示指定线程的运行堆栈
5.thread -b, 找出当前阻塞其他线程的线程
有时候我们发现应用卡住了, 通常是由于某个线程拿住了某个锁, 并且其他线程都在等待这把锁造成的。 为了排查这类问题, arthas 提供了thread -b
, 一键找出那个罪魁祸首。
注意, 目前只支持找出 synchronized 关键字阻塞住的线程, 如果是
java.util.concurrent.Lock
, 目前还不支持。
6.thread -i, 指定采样时间间隔
thread -i 1000
: 统计最近 1000ms 内的线程 CPU 时间。thread -n 3 -i 1000
: 列出 1000ms 内最忙的 3 个线程栈
7.thread --state ,查看指定状态的线程
jvm
查看当前 JVM 信息
结果如下:
[arthas@776]$ jvm
RUNTIME
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MACHINE-NAME 776@MSI
JVM-START-TIME 2022-08-12 14:07:16
MANAGEMENT-SPEC-VERSION 1.2
SPEC-NAME Java Virtual Machine Specification
SPEC-VENDOR Oracle Corporation
SPEC-VERSION 1.8
VM-NAME Java HotSpot(TM) 64-Bit Server VM
VM-VENDOR Oracle Corporation
VM-VERSION 25.201-b09
INPUT-ARGUMENTS []
CLASS-PATH arthas-demo.jar
BOOT-CLASS-PATH D:\devSoft\java8\jre1.8.0_201\lib
esources.jar;D:\devSoft\java8\jre1.8.0_201\lib
t.jar;D:\devSoft\java8\jre1.8.0_201\lib\sunrsasign.jar;D:\devSoft\java8\jre1.8.0_201\lib\jsse.jar;D:\devSoft\java8\jre1.8.0_201\lib\jce
.jar;D:\devSoft\java8\jre1.8.0_201\lib\charsets.jar;D:\devSoft\java8\jre1.8.0_201\lib\jfr.jar;D:\devSoft\java8\jre1.8.0_201\classes
LIBRARY-PATH C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\
Common Files\Oracle\Java\javapath;E:\soft\VMware\VMware Workstation\bin\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Win
dows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;D:\devSoft\ja
va8\jdk1.8.0_201\bin;D:\devSoft\java8\jdk1.8.0_201\jre\bin;D:\devSoft\apache-maven-3.8.1\bin;D:\devSoft\nodejs\;C:\Program Files\NVIDIA
Corporation\NVIDIA NvDLISR;C:\Program Files (x86)\dotnet\;C:\Program Files\Docker\Docker
esources\bin;C:\ProgramData\DockerDesktop\version-bin;D:\devSoft\gradle-7.2\bin;D:\devSoft\Git\cmd;D:\devSoft\Go\bin;D:\devSoft\apache-
cassandra-3.9\bin;D:\devSoft\Python27;C:\Program Files\dotnet\;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;C:\Users\MSI-\AppData\
Roaming\npm;D:\devSoft\Microsoft VS Code\bin;%USERPROFILE%\go\bin;E:\soft\Tencent\QQGameTempest\Hall.57795\;E:\soft\Fiddler;.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CLASS-LOADING
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LOADED-CLASS-COUNT 4789
TOTAL-LOADED-CLASS-COUNT 4790
UNLOADED-CLASS-COUNT 1
IS-VERBOSE false
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
COMPILATION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
NAME HotSpot 64-Bit Tiered Compilers
TOTAL-COMPILE-TIME 7675
[time (ms)]
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
GARBAGE-COLLECTORS
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PS Scavenge name : PS Scavenge
[count/time (ms)] collectionCount : 56
collectionTime : 77
PS MarkSweep name : PS MarkSweep
[count/time (ms)] collectionCount : 53
collectionTime : 1088
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MEMORY-MANAGERS
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CodeCacheManager Code Cache
Metaspace Manager Metaspace
Compressed Class Space
PS Scavenge PS Eden Space
PS Survivor Space
PS MarkSweep PS Eden Space
PS Survivor Space
PS Old Gen
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MEMORY
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
HEAP-MEMORY-USAGE init : 534773760(510.0 MiB)
[memory in bytes] used : 157008192(149.7 MiB)
committed : 452460544(431.5 MiB)
max : 7583301632(7.1 GiB)
NO-HEAP-MEMORY-USAGE init : 2555904(2.4 MiB)
[memory in bytes] used : 45266208(43.2 MiB)
committed : 46530560(44.4 MiB)
max : -1(-1 B)
PENDING-FINALIZE-COUNT 0
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OPERATING-SYSTEM
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OS Windows 10
ARCH amd64
PROCESSORS-COUNT 16
LOAD-AVERAGE -1.0
VERSION 10.0
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
THREAD
COUNT 48
DAEMON-COUNT 47
PEAK-COUNT 51
STARTED-COUNT 55
DEADLOCK-COUNT 0
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
FILE-DESCRIPTOR
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MAX-FILE-DESCRIPTOR-COUNT -1
OPEN-FILE-DESCRIPTOR-COUNT -1
[arthas@776]$
THREAD 相关
- COUNT: JVM 当前活跃的线程数
- DAEMON-COUNT: JVM 当前活跃的守护线程数
- PEAK-COUNT: 从 JVM 启动开始曾经活着的最大线程数
- STARTED-COUNT: 从 JVM 启动开始总共启动过的线程次数
- DEADLOCK-COUNT: JVM 当前死锁的线程数
文件描述符相关
- MAX-FILE-DESCRIPTOR-COUNT:JVM 进程最大可以打开的文件描述符数
- OPEN-FILE-DESCRIPTOR-COUNT:JVM 当前打开的文件描述符数
sysprop
查看当前 JVM 的系统属性(System Property
)
查看所有属性:
查看单个属性:
修改单个属性:
getstatic
通过 getstatic 命令可以方便的查看类的静态属性。使用方法为getstatic class_name field_name
- 指定 classLoader
注意 hashcode 是变化的,需要先查看当前的 ClassLoader 信息,使用sc -d <ClassName>
提取对应 ClassLoader 的 hashcode。
如果你使用-c
,你需要手动输入 hashcode:-c <hashcode>
sysenv
查看当前JVM的环境属性(System Environment Variables
)
举例:
#查看所有环境变量
sysenv
#查看单个环境变量
sysenv USERNAME
vmoption
查看,更新 VM 诊断相关的参数
#查看所有的选项
vmoption
#查看指定的选项
vmoption PrintGCDetails
# 修改指定选项
vmoption PrintGCDetails true
ognl
用于执行 ognl 表达式
参数名称 | 参数说明 |
---|---|
express | 执行的表达式 |
[c:] |
执行表达式的 ClassLoader 的 hashcode,默认值是 SystemClassLoader |
[classLoaderClass:] |
指定执行表达式的 ClassLoader 的 class name |
[x] | 结果对象的展开层次,默认值 1 |
-
OGNL 特殊用法请参考:https://github.com/alibaba/arthas/issues/71OGNL
-
表达式官方指南:https://commons.apache.org/proper/commons-ognl/language-guide.html
调用静态函数:
ognl '@java.lang.System@out.println("hello")'
获取静态类的静态字段:
ognl '@demo.MathGame@random'
通过 hashcode 指定 ClassLoader:
classloader -t
ognl -c 5c647e05 @demo.MathGame@random
执行多行表达式,赋值给临时变量,返回一个 List:
ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
heapdump
dump java heap, 类似 jmap 命令的 heap dump 功能。
示例:dump到指定文件:
heapdump D:/dump.hprof
dump下来后,可以通过jhat
命令分析dump文件:
jhat dump.hprof
浏览器访问localhost:7000:
mbean
这个命令可以便捷的查看或监控 Mbean 的属性信息。
参数说明:
参数名称 | 参数说明 |
---|---|
name-pattern | 名称表达式匹配 |
attribute-pattern | 属性名表达式匹配 |
[m] | 查看元信息 |
[i:] | 刷新属性值的时间间隔 (ms) |
[n:] | 刷新属性值的次数 |
[E] | 开启正则表达式匹配,默认为通配符匹配。仅对属性名有效 |
1.列出所有 Mbean 的名称:
2.查看 Mbean 的元信息:
3.查看 mbean 属性信息:
4.mbean 的 name 支持通配符匹配:
5.通配符匹配特定的属性字段:
memory
查看 JVM 内存信息。
vmtool
vmtool
利用JVMTI
接口,实现查询内存对象,强制 GC 等功能。
获取对象
$ vmtool --action getInstances --className java.lang.String --limit 10
@String[][
@String[com/taobao/arthas/core/shell/session/Session],
@String[com.taobao.arthas.core.shell.session.Session],
@String[com/taobao/arthas/core/shell/session/Session],
@String[com/taobao/arthas/core/shell/session/Session],
@String[com/taobao/arthas/core/shell/session/Session.class],
@String[com/taobao/arthas/core/shell/session/Session.class],
@String[com/taobao/arthas/core/shell/session/Session.class],
@String[com/],
@String[java/util/concurrent/ConcurrentHashMap$ValueIterator],
@String[java/util/concurrent/locks/LockSupport],
]
通过
--limit
参数,可以限制返回值数量,避免获取超大数据时对 JVM 造成压力。默认值是 10。
指定 classloader name
vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContext
指定 classloader hash
可以通过sc
命令查找到加载 class 的 classloader。
$ sc -d org.springframework.context.ApplicationContext
class-info org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext
code-source file:/private/tmp/demo-arthas-spring-boot.jar!/BOOT-INF/lib/spring-boot-1.5.13.RELEASE.jar!/
name org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext
...
class-loader +-org.springframework.boot.loader.LaunchedURLClassLoader@19469ea2
+-sun.misc.Launcher$AppClassLoader@75b84c92
+-sun.misc.Launcher$ExtClassLoader@4f023edb
classLoaderHash 19469ea2
然后用-c
/--classloader
参数指定:
vmtool --action getInstances -c 19469ea2 --className org.springframework.context.ApplicationContext
指定返回结果展开层数
getInstances
action 返回结果绑定到instances
变量上,它是数组。通过
-x
/--expand
参数可以指定结果的展开层次,默认值是 1。
vmtool --action getInstances -c 19469ea2 --className org.springframework.context.ApplicationContext -x 2
执行表达式
getInstances
action 返回结果绑定到instances
变量上,它是数组。可以通过--express
参数执行指定的表达式。
vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContext --express 'instances[0].getBeanDefinitionNames()'
强制 GC
vmtool --action forceGc
可以结合 vmoption
命令动态打开PrintGC
开关。