万恶淫为首,百善孝为先
Arthas命令
可以查看相应的文档: https://arthas.aliyun.com/doc/命令.html
如: https://arthas.aliyun.com/doc/grep.html
https://arthas.aliyun.com/doc/cat.html
基础命令
help 查看命令帮助信息
cat 查看当前arthas 系统中的任意文件内容
/usr/local 目录下有一个 yjl.p12 的文件
cat /usr/local/yjl.p12
echo 打印参数
注意,不能打印 当前系统的参数信息
[arthas@4009]$ echo Hello
Hello
[arthas@4009]$ echo $PATH
$PATH
[arthas@4009]$
在linux系统中使用 echo 命令时:
[root@localhost local]# echo HELLO
HELLO
[root@localhost local]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/jdk1.8.0_212/bin:/usr/local/jdk1.8.0_212/jre/bin:/root/bin
[root@localhost local]#
grep 筛选查看
sysprop | grep java
参数列表 | 作用 |
---|---|
-n | 显示行号 |
-i | 忽略大小写 |
-m 行数 | 最大显示行数 |
-e 正则表达式 | 使用正则查找 |
-n 显示行号
grep java -n
[arthas@4009]$ sysprop |grep java -n
5: java.specification.version 1.8
8: java.class.path math-game.jar
9: java.vm.vendor Oracle Corporation
11: java.vendor.url http://java.oracle.com/
14: java.vm.specification.version 1.8
16: sun.java.launcher SUN_STANDARD
18: sun.java.command math-game.jar
22: java.specification.vendor Oracle Corporation
23: java.home /usr/local/jdk1.8.0_212/jre
26: java.vm.specification.vendor Oracle Corporation
27: java.specification.name Java Platform API Specification
28: java.awt.graphicsenv sun.awt.X11GraphicsEnvironment
32: java.runtime.version 1.8.0_212-b10
36: java.endorsed.dirs /usr/local/jdk1.8.0_212/jre/lib/endorsed
37: java.runtime.name Java(TM) SE Runtime Environment
39: java.vm.name Java HotSpot(TM) 64-Bit Server VM
40: java.vendor.url.bug http://bugreport.sun.com/bugreport/
41: java.io.tmpdir /tmp
-i 忽略大小写
sysprop |grep Java -i
54: java.class.version 52.0
[arthas@4009]$ sysprop |grep Java
java.specification.name Java Platform API Specification
java.runtime.name Java(TM) SE Runtime Environment
java.vm.name Java HotSpot(TM) 64-Bit Server VM
java.vm.specification.name Java Virtual Machine Specification
[arthas@4009]$ sysprop |grep JaVA
[arthas@4009]$ sysprop |grep JaVA -i
java.specification.version 1.8
java.class.path math-game.jar
java.vm.vendor Oracle Corporation
java.vendor.url http://java.oracle.com/
java.vm.specification.version 1.8
sun.java.launcher SUN_STANDARD
sun.java.command math-game.jar
-m 数字 最多展示几条
sysprop |grep JaVA -i -m 5 -n
[arthas@4009]$ sysprop |grep JaVA -i -m 5 -n
5: java.specification.version 1.8
8: java.class.path math-game.jar
9: java.vm.vendor Oracle Corporation
11: java.vendor.url http://java.oracle.com/
14: java.vm.specification.version 1.8
-e 正则表达式
[arthas@4009]$ sysprop |grep JaVA -i -m 4 -n -e "a{5}"
5: java.specification.version 1.8
8: java.class.path math-game.jar
9: java.vm.vendor Oracle Corporation
11: java.vendor.url http://java.oracle.com/
base64 编码转换
base64 -h
将信息写入到文件里面
[arthas@4009]$
[arthas@4009]$ echo 'Hello YJL' > /tmp/test.txt
[arthas@4009]$ cat /tmp/test.txt
Hello YJL
进行编码:
[arthas@4009]$ base64 /tmp/test.txt
SGVsbG8gWUpMCg==
[arthas@4009]$ // 输出到具体的文件里面
[arthas@4009]$ base64 --input /tmp/test.txt --output /tmp/result.txt
[arthas@4009]$ cat /tmp/result.txt
SGVsbG8gWUpMCg==
进行解码
// -d 表示解码
[arthas@4009]$ base64 -d /tmp/result.txt
Hello YJL
[arthas@4009]$ base64 -d /tmp/result.txt --output /tmp/source.txt
[arthas@4009]$ cat /tmp/source.txt
Hello YJL
pwd 返回当前的目录
[arthas@4009]$ pwd
/usr/local/arthas3.6.1
cls 清空屏幕
[arthas@4009]$ cls
session 查看当前会话信息
[arthas@4009]$ session
Name Value
--------------------------------------------------
JAVA_PID 4009
SESSION_ID f1330c2f-66c3-4e3e-9510-de90b7e6af44
[arthas@4009]$
version 查询版本号
[arthas@4009]$ version
3.6.1
history 查看历史
[arthas@4009]$ history
1 thread
2 help
3 cat /usr/local/yjl.p12
4 XshellXshellXshellXshellXshellXshellXshellXshell
5 echo $PATH
6 echo $PATH$
7 echo PATH
8 echo PATH
9 echo $PATH
10 clear
11 cls
12 echo Hello
13 echo $PATH
14 sysprop |grep java
15 echo 'Hello YJL' > /temp/test.txt
16 cat /tmp/test.txt
quit /exit 退出当前客户端
只退出当前的连接,不会让其他的 Arthas客户端退出。
[arthas@4009]$ exit
[arthas@4009]$ stop
stop 关闭 Arthas服务
关闭 Arthas服务,所有的 Arthas客户端都会退出。
[arthas@4009]$ stop
Resetting all enhanced classes ...
Affect(class count: 0 , method count: 0) cost in 3 ms, listenerId: 0
Arthas Server is going to shutdown...
[arthas@4009]$ session (49ae3bce-24cb-47c5-8b98-1dc07d215f41) is closed because server is going to shutdown.
另外非 stop 的客户端会展示 信息:
[arthas@4009]$ session (92a01e98-82b7-4d10-82c2-64806a851d5e) is closed because server is going to shutdown.
keymap 展示快捷键
[arthas@4009]$ keymap
Shortcut Description Name
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
"\C-a" Ctrl + a beginning-of-line
"\C-e" Ctrl + e end-of-line
"\C-f" Ctrl + f forward-word
"\C-b" Ctrl + b backward-word
"\e[D" Left arrow backward-char
"\e[C" Right arrow forward-char
"\e[A" Up arrow history-search-backward
"\e[B" Down arrow history-search-forward
"\C-h" Ctrl + h backward-delete-char
"\C-?" Ctrl + ? backward-delete-char
"\C-u" Ctrl + u undo
"\C-d" Ctrl + d delete-char
"\C-k" Ctrl + k kill-line
"\C-i" Ctrl + i complete
"\C-j" Ctrl + j accept-line
"\C-m" Ctrl + m accept-line
"\C-w" Ctrl + w backward-delete-word
"\C-x\e[3~" "\C-x\e[3~" backward-kill-line
"\e\C-?" "\e\C-?" backward-kill-word
"\e[1~" "\e[1~" beginning-of-line
"\e[4~" "\e[4~" end-of-line
"\e[5~" "\e[5~" beginning-of-history
"\e[6~" "\e[6~" end-of-history
"\e[3~" "\e[3~" delete-char
"\e[2~" "\e[2~" quoted-insert
"\e[7~" "\e[7~" beginning-of-line
"\e[8~" "\e[8~" end-of-line
"\eOH" "\eOH" beginning-of-line
"\eOF" "\eOF" end-of-line
"\e[H" "\e[H" beginning-of-line
"\e[F" "\e[F" end-of-line
[arthas@4009]$
快捷键 | 快捷键说明 | 命令名称 | 命令说明 |
---|---|---|---|
“\C-a” | ctrl + a | beginning-of-line | 跳到行首 |
“\C-e” | ctrl + e | end-of-line | 跳到行尾 |
“\C-f” | ctrl + f | forward-word | 向前移动一个单词 |
“\C-b” | ctrl + b | backward-word | 向后移动一个单词 |
“\e[D” | 键盘左方向键 | backward-char | 光标向前移动一个字符 |
“\e[C” | 键盘右方向键 | forward-char | 光标向后移动一个字符 |
“\e[B” | 键盘下方向键 | next-history | 下翻显示下一个命令 |
“\e[A” | 键盘上方向键 | previous-history | 上翻显示上一个命令 |
“\C-h” | ctrl + h | backward-delete-char | 向后删除一个字符 |
“\C-?” | ctrl + shift + / | backward-delete-char | 向后删除一个字符 |
“\C-u” | ctrl + u | undo | 撤销上一个命令,相当于清空当前行 |
“\C-d” | ctrl + d | delete-char | 删除当前光标所在字符 |
“\C-k” | ctrl + k | kill-line | 删除当前光标到行尾的所有字符 |
“\C-i” | ctrl + i | complete | 自动补全,相当于敲TAB |
“\C-j” | ctrl + j | accept-line | 结束当前行,相当于敲回车 |
“\C-m” | ctrl + m | accept-line | 结束当前行,相当于敲回车 |
“\C-w” | backward-delete-word | ||
“\C-x\e[3~” | backward-kill-line | ||
“\e\C-?” | backward-kill-word |
- 任何时候 tab 键,会根据当前的输入给出提示
- 命令后敲 - 或 – ,然后按 tab 键,可以展示出此命令具体的选项
[arthas@4009]$ watch --
expand sizeLimit regex limits before finish exception success listenerId verbose exclude-class-pattern
[arthas@4009]$ trace --
regex limits path skipJDKMethod listenerId verbose exclude-class-pattern
自定义快捷键,采用文件引用的方式。 需要创建 $USER_HOME/.arthas/conf/inputrc 文件,里面填充默认的配置后,再进行追加指令。
reset 重置 增强类
重置增强类,将 Arthas 增加过的类全部还原。
stop 时也会重置 所有增强过的类
reset -h
重置指定的类
[arthas@4009]$ reset demo.MathGame
Affect(class count: 0 , method count: 0) cost in 3 ms, listenerId: 0
重置正则验证的类
[arthas@4009]$ reset demo.*
Affect(class count: 0 , method count: 0) cost in 0 ms, listenerId: 0
重置 全部的类
[arthas@4009]$ reset
Affect(class count: 0 , method count: 0) cost in 0 ms, listenerId: 0
一个窗口执行:
arthas@4009]$ trace demo.MathGame run
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 146 ms, listenerId: 2
`---ts=2022-05-05 19:38:40;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@70dea4e
`---[1.595792ms] demo.MathGame:run()
`---[21.81% 0.348055ms ] demo.MathGame:primeFactors() #24 [throws Exception]
`---ts=2022-05-05 19:38:41;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@70dea4e
`---[5.22506ms] demo.MathGame:run()
+---[65.39% 3.416532ms ] demo.MathGame:primeFactors() #24
`---[22.02% 1.15062ms ] demo.MathGame:print() #25
另外一个窗口:
reset demo.MathGame
[arthas@4009]$ reset demo.MathGame
Affect(class count: 1 , method count: 0) cost in 62 ms, listenerId: 0
JVM 相关的
dashboard 当前系统的实时数据面板
查看当前系统的实时数据面板。 ctrl+c 退出
参数名称 | 参数说明 |
---|---|
i | 刷新的时间间隔 默认 5000ms |
n | 刷新的次数 |
命令:
// 全部展示
dashboard
// 每隔1000ms 刷新一次
dashboard -i 1000
// 只刷新3 次
dashboard -n 3
// 1000ms刷新一次,只刷新3次
dashboard -n 3 -i 1000
thread 查看当前JVM的堆栈线程信息
展示信息 | 解释 |
---|---|
ID | 线程ID |
NAME | 线程名 |
GROUP | 线程组名 |
PRIORITY | 线程优先级, 1~10之间的数字。越大表示优先级越高 |
STATE | 线程的状态 有 NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATED |
CPU% | 线程的 CPU使用率。 采样间隔1000ms,某个线程的增量cpu时间为100ms,则cpu使用率=100/1000=10% |
DELTA_TIME | 上次采样之后线程运行增量 CPU时间。 数据格式为秒 |
TIME | 线程运行总CPU时间。 格式为 分:秒 |
INTERRUPTED | 中断位状态 |
DAEMON | 是否是守护线程 |
命令参数信息:
参数名称 | 参数说明 |
---|---|
d | 指定线程的id thread 1 会显示第一列。按照 CPU增量时间降序排列 |
n | 指定最忙的前n个,并打印 thread -n 3 |
b | 找出当前阻塞其它线程的线程 thread -b 查找死锁的那个 |
i value | 指定cpu占比统计的采样间隔 单位为毫秒 thread -i 1000 |
–all | 显示所有匹配的线程 thread --all |
thread -b 查询阻塞的
目前只支持找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持。
thread --state BLOCKED 根据状态进行查询
[arthas@4009]$ thread --state BLOCKED
Threads Total: 15, NEW: 0, RUNNABLE: 8, BLOCKED: 0, WAITING: 4, TIMED_WAITING: 3, TERMINATED: 0
ID NAME GROUP PRIORITY STATE %CPU DELTA_TIME TIME INTERRUPTED DAEMON
jvm 查看当前 JVM的信息
[arthas@4009]$ jvm
RUNTIME
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MACHINE-NAME 4009@localhost.localdomain
JVM-START-TIME 2022-05-05 17:21:44
MANAGEMENT-SPEC-VERSION 1.2
SPEC-NAME Java Virtual Machine Specification
sysprop 查看当前JVM的系统属性
// 展示查看全部
sysprop
// 展示某一个属性
sysprop production.mode
// 修改某一个属性
sysprop production.mode true
sysenv 当前 JVM的环境信息
// 查询全部
sysenv
// 查询单个属性
[arthas@4009]$ sysenv PATH
KEY VALUE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/jdk1.8.0_212/bin:/usr/local/jdk1.8.0_212/jre/bin:/root/bin
vmoption 查看更新 VM 诊断相关的参数
//查看全部
vmoption
// 查看单个属性
vmoption PrintGC
// 更新单个属性
vmoption PrintGC true
getstatic 查看类的静态属性
getstatic 类 属性
[arthas@4009]$ getstatic demo.MathGame random
field: random
@Random[
serialVersionUID=@Long[3905348978240129619],
seed=@AtomicLong[14012594744482],
multiplier=@Long[25214903917],
addend=@Long[11],
mask=@Long[281474976710655],
DOUBLE_UNIT=@Double[1.1102230246251565E-16],
BadBound=@String[bound must be positive],
BadRange=@String[bound must be greater than origin],
BadSize=@String[size must be non-negative],
seedUniquifier=@AtomicLong[3620162808252824828],
nextNextGaussian=@Double[0.0],
haveNextNextGaussian=@Boolean[false],
serialPersistentFields=@ObjectStreamField[][isEmpty=false;size=3],
unsafe=@Unsafe[sun.misc.Unsafe@20966a3a],
seedOffset=@Long[24],
]
Affect(row-cnt:1) cost in 30 ms.
ognl 查看类的静态属性和方法
ognl '@demo.MathGame@random'
ognl '@demo.MathGame@random' -x 2
class/classloader 相关的
sc 查看 JVM 已加载的类信息
查看 JVM 已加载的类信息。 sc 为 search class 的简写。 能搜索到所有已经加载到 JVM 中的 Class 信息。
sc 默认开启了子类匹配功能,也就是说所有当前类的子类也会被搜索出来,
想要精确的匹配,请打开 options disable-sub-class true
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
[d] | 输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。 如果一个类被多个ClassLoader所加载,则会出现多次 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[f] | 输出当前类的成员变量信息(需要配合参数-d一起使用) |
[x:] | 指定输出静态变量时属性的遍历深度,默认为 0,即直接使用 toString 输出 |
[c:] | 指定class的 ClassLoader 的 hashcode |
[classLoaderClass:] | 指定执行表达式的 ClassLoader 的 class name |
[n:] | 具有详细信息的匹配类的最大数量(默认为100) |
查询某个类:
[arthas@3075]$ sc demo.*
demo.MathGame
查询该类的详细信息:
[arthas@3075]$ sc -d demo.MathGame
class-info demo.MathGame
code-source /usr/local/arthas3.6.1/math-game.jar
name demo.MathGame
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name MathGame
modifier public
annotation
interfaces
super-class +-java.lang.Object
class-loader +-sun.misc.Launcher$AppClassLoader@70dea4e
+-sun.misc.Launcher$ExtClassLoader@1b6d3586
classLoaderHash 70dea4e
Affect(row-cnt:1) cost in 26 ms.
查询打印 Field 属性信息。 看类里面的属性
[arthas@3075]$ sc -d -f demo.MathGame
class-info demo.MathGame
code-source /usr/local/arthas3.6.1/math-game.jar
name demo.MathGame
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name MathGame
modifier public
annotation
interfaces
super-class +-java.lang.Object
class-loader +-sun.misc.Launcher$AppClassLoader@70dea4e
+-sun.misc.Launcher$ExtClassLoader@1b6d3586
classLoaderHash 70dea4e // 会添加这些信息
fields name random
type java.util.Random
modifier private,static
value java.util.Random@3c424379
name illegalArgumentCount
type int
modifier private
Affect(row-cnt:1) cost in 29 ms.
sm 查看已加载类的方法信息
sm 为 search method 的简写,能搜索出所有已经加载了 Class 信息的方法信息。
sm 只能看到当前类所声明的方法,父类无法看到。
查看 类里面的所有 方法
[arthas@3075]$ sm demo.MathGame
demo.MathGame <init>()V
demo.MathGame primeFactors(I)Ljava/util/List;
demo.MathGame main([Ljava/lang/String;)V
demo.MathGame run()V
demo.MathGame print(ILjava/util/List;)V
Affect(row-cnt:5) cost in 17 ms.
查看类里面某个方法的具体定义
[arthas@3075]$ sm -d demo.MathGame primeFactors
declaring-class demo.MathGame
method-name primeFactors
modifier public
annotation
parameters int
return java.util.List
exceptions
classLoaderHash 70dea4e
jad 反编辑指定已加载类的源码
jad 命令 将 JVM 实际运行的 class 的 字节码反编码成 Java 代码, 便于理解业务逻辑。 可能会存在语法错误,但不影响理解。
查看某个具体的类的源码:
jad demo.MathGame
也可以查看具体的某个方法的源码
jad demo.MathGame print
只展示源码:
jad --source-only demo.MathGame print
反编辑时,去掉行号
jad --source-only demo.MathGame print --lineNumber false
反编辑时, 将编译好的代码 放置到其它目录下:
jad --source-only demo.MathGame --lineNumber false > /tmp/MathGame.java
反编辑时指定 ClassLoader
一个类 ,存在于多个 jar 包里面。 即多个 jar包里面,都有相同的全限定类信息
-- 编辑这个类
$ jad org.apache.log4j.Logger
Found more than one class for: org.apache.log4j.Logger, Please use jad -c hashcode org.apache.log4j.Logger
HASHCODE CLASSLOADER
69dcaba4 +-monitor's ModuleClassLoader
6e51ad67 +-java.net.URLClassLoader@6e51ad67
+-sun.misc.Launcher$AppClassLoader@6951a712
+-sun.misc.Launcher$ExtClassLoader@6fafc4c2
2bdd9114 +-pandora-qos-service's ModuleClassLoader
4c0df5f8 +-pandora-framework's ModuleClassLoader
Affect(row-cnt:0) cost in 38 ms.
-- 使用命令 -c 指定类加载器
$ jad org.apache.log4j.Logger -c 69dcaba4
ClassLoader:
+-monitor's ModuleClassLoader
Location:
/Users/admin/app/log4j-1.2.14.jar
package org.apache.log4j;
import org.apache.log4j.spi.*;
public class Logger extends Category
{
private static final String FQCN;
protected Logger(String name)
{
super(name);
}
...
Affect(row-cnt:1) cost in 190 ms.
mc 编辑 将 .java 文件变成 .class 文件
编译 目录下的 .java 文件
[arthas@3075]$ mc /tmp/MathGame.java
Memory compiler output:
/usr/local/arthas3.6.1/demo/MathGame.class
Affect(row-cnt:1) cost in 2274 ms.
会放置到默认目录下。
可以通过 -d 来指定目录 mc -d 放置的目录 要编译的 .java文件目录
[arthas@3075]$ mc -d /tmp/ /tmp/MathGame.java
Memory compiler output:
/tmp/demo/MathGame.class
Affect(row-cnt:1) cost in 206 ms.
当类存在多个时,可以指定类加载器
先查询类加载器
[arthas@3075]$ sc -d demo.MathGame |grep classLoaderHash
classLoaderHash 70dea4e
[arthas@3075]$ mc -c 70dea4e -d /tmp/ /tmp/MathGame.java
Memory compiler output:
/tmp/demo/MathGame.class
Affect(row-cnt:1) cost in 176 ms.
retransform 加载外部的 .class 文件
替换相应的 .class 文件
加载 .class 文件
[arthas@3075]$ retransform /tmp/demo/MathGame.class
retransform success, size: 1, classes:
demo.MathGame
查看加载的信息:
针对的是服务器文件:
[arthas@3075]$ retransform -l
Id ClassName TransformCount LoaderHash LoaderClassName
1 demo.MathGame 1 null null
删除回滚 .class 文件
// (1为序号)
[arthas@3075]$ retransform -d 1
[arthas@3075]$ retransform -l
Id ClassName TransformCount LoaderHash LoaderClassName
[arthas@3075]$
再查询时,就变成了 null
回滚所有的 .class 文件
retransform --deleteAll
限制:
- 不允许新增加field/method
- 正在跑的函数,没有退出不能生效,
redefine 加载外部的 .class 文件
与 retransform 命令一样,以前使用的是 redefine , 现在推荐使用 retransform
reset命令对redefine的类无效。如果想重置,需要redefine原始的字节码。
[arthas@3075]$ redefine /tmp/demo/MathGame.class
redefine success, size: 1, classes:
demo.MathGame
限制:
- 不允许新增加field/method
- 正在跑的函数,没有退出不能生效,
dump 加载类的字节码到特定目录
下载类的字节码
[arthas@3075]$ dump demo.MathGame
HASHCODE CLASSLOADER LOCATION
70dea4e +-sun.misc.Launcher$AppClassLoader@70dea4e /root/logs/arthas/classdump/sun.misc.Launcher$AppClassLoader-70dea4e/demo/MathGame.class
+-sun.misc.Launcher$ExtClassLoader@1b6d3586
Affect(row-cnt:1) cost in 51 ms.
可以放置在指定的目录下
-d 指定目录
[arthas@3075]$ dump -d /tmp/ demo.MathGame
HASHCODE CLASSLOADER LOCATION
70dea4e +-sun.misc.Launcher$AppClassLoader@70dea4e /tmp/sun.misc.Launcher$AppClassLoader-70dea4e/demo/MathGame.class
+-sun.misc.Launcher$ExtClassLoader@1b6d3586
Affect(row-cnt:1) cost in 52 ms.
[arthas@3075]$
放置类
dump demo.*
dump java.lang.*
classloader 查看继承树
classloader 命令将 JVM 中所有的classloader的信息统计出来,并可以展示继承树,urls等
按照类加载类型查看统计信息
[arthas@3075]$ classloader
name numberOfInstances loadedCountTotal
BootstrapClassLoader 1 2478
com.taobao.arthas.agent.ArthasClassloader 1 2363
java.net.FactoryURLClassLoader 1 826
sun.misc.Launcher$ExtClassLoader 1 45
sun.misc.Launcher$AppClassLoader 1 4
sun.reflect.DelegatingClassLoader 3 3
Affect(row-cnt:6) cost in 11 ms.
[arthas@3075]$
按照类加载实例查看统计信息
[arthas@3075]$ classloader -l
name loadedCount hash parent
BootstrapClassLoader 2478 null null
com.taobao.arthas.agent.ArthasClassloader@6667d90a 2366 6667d90a sun.misc.Launcher$ExtClassLoader@1b6d3586
java.net.FactoryURLClassLoader@3a6a4563 826 3a6a4563 sun.misc.Launcher$AppClassLoader@70dea4e
sun.misc.Launcher$AppClassLoader@70dea4e 4 70dea4e sun.misc.Launcher$ExtClassLoader@1b6d3586
sun.misc.Launcher$ExtClassLoader@1b6d3586 45 1b6d3586 null
Affect(row-cnt:5) cost in 16 ms.
[arthas@3075]$
查看继承树
[arthas@3075]$ classloader -t
+-BootstrapClassLoader
+-sun.misc.Launcher$ExtClassLoader@1b6d3586
+-com.taobao.arthas.agent.ArthasClassloader@6667d90a
+-sun.misc.Launcher$AppClassLoader@70dea4e
+-java.net.FactoryURLClassLoader@3a6a4563
Affect(row-cnt:5) cost in 6 ms.
查询该 jar包下的资源, 对于 ResourceNotFoundException 异常非常有用。
查询的是 AppClassLoader
[arthas@3075]$ classloader -c 70dea4e -r META-INF/MANIFEST.MF
jar:file:/usr/local/arthas3.6.1/math-game.jar!/META-INF/MANIFEST.MF
jar:file:/usr/local/arthas3.6.1/arthas-agent.jar!/META-INF/MANIFEST.MF
Affect(row-cnt:2) cost in 4 ms.
[arthas@3075]$
monitor /watch /trace 相关
monitor 对类,方法的调用进行监控
monitor 是一个非实时返回的命令。 是不断的等待目标Java 进程返回信息,直到用户输入 ctrl +C 为止.
monitor 类 方法 筛选条件
其中 -c 参数 是统计周期,默认为 120秒.
monitor -c 5 demo.MathGame primeFactors
[arthas@3292]$ monitor -c 5 demo.MathGame primeFactors
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 174 ms, listenerId: 2
timestamp class method total success fail avg-rt(ms) fail-rate
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022-05-09 08:58:02 demo.MathGame primeFactors 4 2 2 7.95 50.00%
timestamp class method total success fail avg-rt(ms) fail-rate
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022-05-09 08:58:07 demo.MathGame primeFactors 5 2 3 3.78 60.00%
timestamp class method total success fail avg-rt(ms) fail-rate
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022-05-09 08:58:12 demo.MathGame primeFactors 5 4 1 0.60 20.00%
timestamp class method total success fail avg-rt(ms) fail-rate
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2022-05-09 08:58:17 demo.MathGame primeFactors 5 4 1 0.12 20.00%
监控项 | 说明 |
---|---|
timestamp | 时间戳 |
class | Java类 |
method | 方法(构造方法、普通方法) |
total | 调用次数 |
success | 成功次数 |
fail | 失败次数 |
rt | 平均RT |
fail-rate | 失败率 |
可以对结果进行相关的筛选.
monitor -c 5 demo.MathGame primeFactors “params[0] <= 2”
值 < = 2 表示都是异常的。
表达式筛选条件,也可以放置在前面。
加上一个参数 -b 表示执行之前
monitor -b -c 5 demo.MathGame primeFactors “params[0] < 2”
只展示失败的信息.
watch 观察指定函数的调用情况
可以观察到 返回值 抛出异常的信息 入参 ,也可以通过编写 OGNL 表达式对变量进行查看
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 函数名表达式匹配 |
express | 观察表达式,默认值:{params, target, returnObj} |
condition-express | 条件表达式 |
[b] | 在函数调用之前观察 before |
[e] | 在函数异常之后观察 exception |
[s] | 在函数返回之后观察 success |
[f] | 在函数结束之后(正常返回和异常返回)观察 finish |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[x:] | 指定输出结果的属性遍历深度,默认为 1,最大值是4 这个常用. |
查看默认的信息
watch demo.MathGame primeFactors
可以看到,返回的信息展示不清楚。 可以再向下一级扩展一下
用 -x 参数指定
watch demo.MathGame primeFactors -x 2
查看函数调用入口 的参数和返回值
watch demo.MathGame primeFactors “{params,returnObj}” -x 2 -b
观察函数调用前和函数调用后
-b 返回之前 -s 表示之后 -n 2 指定执行的次数. 为 2次
watch demo.MathGame primeFactors “{params,target,returnObj}” -x 2 -b -s -n 2
可以使用条件表达式
watch demo.MathGame primeFactors “{params[0],target}” “params[0] < 0”
观察异常的信息
watch demo.MathGame primeFactors “{params[0],throwExp}” -e -x 2 -n 2
根据 #cost 进行过滤
watch demo.MathGame primeFactors “params,returnObj” ‘#cost>200’ -x 2
![](https://img-blog.csdnimg.cn/img_convert/cdf5054320df217ec3336e7bb7692db8.png
查看当前对象, 使用的是 target
watch demo.MathGame primeFactors “{target}” -x 2 -n 1
查看 target 对象里面的某一个属性信息
watch demo.MathGame primeFactors “{target.illegalArgumentCount}” -n 1
trace 搜索对应的方法调用路径 ,渲染和统计整个调用链路上的性能开销
trace demo.MathGame run
指定次数的话,可以使用 -n 1 为指定
trace demo.MathGame run -n 1
展示的信息里面,是没有 jdk 相关的函数的。 可以通过配置 --skipJDKMethod false 为指定
根据花费时间进行验证筛选处理
trace demo.MathGame primeFactors ‘#cost > 10’ -n 1
stack 输出当前方法被调用的路径
知道 一个方法被执行了,但这个方法执行的路径非常多,或者你根本不知道这个方法是从哪儿被执行的,此时就需要 stack 命令。
stack demo.MathGame primeFactors -n 1
可以根据 #cost 花费时间进行过滤
stack demo.MathGame primeFactors ‘#cost > 5’
也可以根据条件表达式进行过滤
stack demo.MathGame primeFactors 'params[0] < 0 ’ -n 2
tt 时空隧道, 记录下指定方法每次调用 的入参和返回信息
如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。
tt 指的是 TimeTunnel
-t 表示每一次执行情况. -n 3 表示 执行的次数
tt -t -n 3 demo.MathGame primeFactors
表格字段 | 字段解释 |
---|---|
INDEX | 时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要。 |
TIMESTAMP | 方法执行的本机时间,记录了这个时间片段所发生的本机时间 |
COST(ms) | 方法执行的耗时 |
IS-RET | 方法是否以正常返回的形式结束 |
IS-EXP | 方法是否以抛异常的形式结束 |
OBJECT | 执行对象的hashCode(),注意,曾经有人误认为是对象在JVM中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体 |
CLASS | 执行的类名 |
METHOD | 执行的方法名 |
tt -l 查询全部
查看当时的调用的信息
tt -i 100
重做调用 -p
tt -i 1000 -p
profiler 生成火焰图
启动
profiler start
查看已经采集的数量
profiler getSamples
查看状态:
profiler status
停止:
profiler stop --format html
也可以使用 profiler stop --format html --file /tmp/result.html 通过 --file 来指定文件的路径
在外部 使用 sz 命令下载该文件,通过浏览器就可以打开观看。
支持的列表
profiler list
profiler start --event alloc lock
恢复采样 profiler resume
start 和 resume 的区别: start 是新开始采样, resume 是保留上次 stop 时的数据,继续开始。