官网地址:https://arthas.aliyun.com/doc/en/index.html
# 命令行输入
curl -0 https://arthas.aliyun.com/arthas-boot.jar --output arthas-boot.jar
# 补充信息-------------------ubuntu 操作系统,在没有curl的情况,可执行命令:
apt-get update
apt install curl
# centos 操作系统jps命令不存在时:
yum install -y java-1.8.0-openjdk-devel.x86_64
# 启动arthas 注意:启动前已经要有java进程运行,否则无法进入
java -jar arthas-boot.jar --telnet-port 9998 --http-port -9999
# 说明:建议增加参数 --telnet-port 和 --http-port 目的:避免端口冲突
说明:第一次执行是会下载arthas的安装包,界面如下:
下载成功后,进入后界面如下:
1、dashboard 仪表板
2、通过thread命令来获取到arthas-demo进程的Main Class
3、通过jad来反编译Main Class
4、watch
5、jvm 虚拟机相关
6、sysprop 系统属性相关
7、sysenv java环境变量
8、vmoption 显示虚拟机中的选项
9、getstatic 获取静态属性
10、ognl 表达式
直接输入命令
dashboard
补充信息:JVM内存区域划分 heap区和非heap区。heap区包括:eden_space、survivor_space、tenured_gen;非heap区包括:code_cache、perm_gen、jvm stack、local method stack
HotSpot虚拟机GC算法采用分代收集算法:
1、一个人(对象)出来(new 出来)后会在Eden Space(伊甸园)无忧无虑的生活,直到GC到来打破了他们平静的生活。GC会逐一问清楚每个对象的情况,有没有钱(此对象的引用)啊,因为GC想赚钱呀,有钱的才可以敲诈嘛。然后富人就会进入Survivor Space(幸存者区),穷人的就直接kill掉。
2、并不是进入Survivor Space(幸存者区)后就保证人身是安全的,但至少可以活段时间。GC会定期(可以自定义)会对这些人进行敲诈,亿万富翁每次都给钱,GC很满意,就让其进入了Genured Gen(养老区)。万元户经不住几次敲诈就没钱了,GC看没有啥价值啦,就直接kill掉了。
3、进入到养老区的人基本就可以保证人身安全啦,但是亿万富豪有的也会挥霍成穷光蛋,只要钱没了,GC还是kill掉。
分区的目的:新生区由于对象产生的比较多并且大都是朝生夕灭的,所以直接采用标记-清理算法。而养老区生命力很强,则采用复制算法,针对不同情况使用不同算法。
非heap区域中Perm Gen中放着类、方法的定义,jvm Stack区域放着方法参数、局域变量等的引用,方法执行顺序按照栈的先入后出方式。
thread
#或
thread 进程id
#参数说明
-n 指定最忙的前N个线程并打印堆栈
-b 找出当前阻塞其他线程的线程
-i 指定cpu占比统计的采样间隔,单位毫秒
--state WAITING 查看所有处于等待状态的线程
jad demo.MathGame
watch demo.MathGame 方法名 返回值
# 查看所有属性
sysprop
#查看单个属性,支持tab不全
sysprop java.version
# 修改
sysprop user.country US
直接输入命令sysenv 或 vmoption 查看所有
输入具体的 sysenv USER 则查看具体user属性
输入vmoption PrintGCDetails true 则直接修改具体项的值
# getstatic 类名 属性名
getstatic demo.MathGame random
# 调用静态函数-获取返回值
ognl '@[email protected]("hello")'
# 获取静态类的静态字段
ognl '@demo.MathGame@random'
# 执行多表达式,赋值给临时变量,返回一个list
ognl '#value1=@System@getProperty("java.home"),#value2=@System@getProperty("java.runtime.name"),{#value1,#value2}'
如果只是退出当前的链接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开发,下载连接时可以直接连接上。
如果想完全退出arthas,可执行stop
命令
help cat grep pwd cls session reset version quit stop keymap history
匹配查找,和linux里的grep命令类似,但只能用于管道命令
举例
# 只显示包含java字符串的系统属性
sysprop | grep java
# 可以增加参数:
-n 显示行号
-i 忽略大小写
-m 行数 最大显示行数
-e "正则表达式" 使用正则表达式
应用
sysprop | grep -e "\d{1,2}" 包含1到2个数字
sysprop | grep -e "\d{2,}" 包含2个数字以上
清屏
重置增强类
reset Test # 还原指定类
reset *List # 还原所有以List结尾的类
reset # 还原所有的类
1、sc:Search Class
2、sm:Search Method
3、jad:把字节码文件反编译成源代码
4、mc:在内存中把源代码编译成字节码文件
5、redefine:把新生成的字节码文件在内存中执行
sc demo.MathGame
或
sc demo.*
# 查看详细信息
sc demo.MathGame -d
# 查看详细信息+成员变量
sc demo.MathGame -df
sm demo.MathGame
# 查看详细信息
sm demo.MathGame -d
jad java.lang.String #包含类加载器
# 只显示源码
jad demo.MathGame --source-only
# 只看其中的一个方法
jad java.lang.String trim
mc /root/Hello.java
# 或指定编译后目录
mc /root/Hello.java -d /root
限制条件:
1、不允许新增加field/method;
2、正在跑的函数,没有退出不能生效;
jad --source-only demo.MathGame > /root/MathGame.java
mc /root/MathGame.java -d /root
redefine /root/demo/MathGame.class
1、dump 将正在JVM中运行的程序的字节码文件提取出来;
2、classloader 获取类加载器的信息;
dump java.lang.String
dump demo.*
作用:
1、显示所有类加载器的信息;
2、获取某个类加载器所在的jar包;
3、获取某个资源在哪个jar包中;
4、加载某个类;
# 执行命令
classloader
# 执行命令
classloader -l
# 执行命令
classloader -c 680f2737
# 执行命令
classloader -c 680f2737 -r java/lang/String.class
# 执行命令
classloader -c 680f2737 -load java.lang.String
作用:用来监视一个时间段中指定方法的执行次数,成功次数,失败次数等;
monitor demo.MathGame primeFactors -c 5
# 观察demo.MathGame类中primeFactors方法入参和返回值,结果属性遍历深度为2
watch demo.MathGame primeFactors "{params,returnObj}" -x 2
# 观察方法入参,对比前一个例子,返回值为空(事件点为方法执行前,因此获取不到返回值)
watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b
# 观察当前对象中的属性,如果想查看方法运行前后,当前对象中的属性,可以使用target关键字,代表当前对象
watch demo.MathGame primeFactors "target" -x 2 -b
# 使用target.field_name访问当前对象的某个属性
watch demo.MathGame primeFactors "target.illegalArgumentCount" -x 2
# 同时观察方法调用前和方法返回后,参数里-n 2,表示只执行两次
watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2
# 条件表达式的例子,输出第1参数小于0的情况
watch demo.MathGame primeFactors "{params,target}" "params[0]<0"
作用:对方法内部调用路径进行追踪,并输出方法路径上的每个节点上耗时;
实战
# trace函数指定类的制定方法
trace demo.MathGame run
# trace函数指定类的制定方法 只追踪2次
trace demo.MathGame run -n 2
# trace函数指定类的制定方法 只追踪2次 也查看jdk里面的方法
trace --skipJDKMethod demo.MathGame run -n 2
# trace函数指定类的制定方法 运行时间大于0.5秒
trace demo.MathGame run "#cost > .5"
作用:输出当前方法被调用的调用路径
实战
# 获取primeFactors的调用路径
stack demo.MathGame primeFactors
# 条件表达式来过滤,第0个参数的值小于0,-n表示获取2次
stack demo.MathGame primeFactors "params[0]<0" -n 2
# 据执行时间类过滤,耗时大于5毫秒
stack demo.MathGame primeFactors "cost>0.5"
作用:time-tunnel 时间隧道
记录下指定方法每次调用的入参和返回信息,并能对这些不同时间下调用的信息进行观测
实战
# 记录下当前方法的每次调用环境现场
tt -t demo.MathGame primeFactors
# 查询之前记录
tt -l
# 查询某一个方法 (搜索现有结果)
tt -s 'method.name=="primeFactors"'
# 查看具体某个INDEX调用的情况
tt -i 1008
# 重新执行某INDEX的调用
tt -i 1008 -p
# 重新执行某INDEX的调用 限制调用3次
tt -i 1008 -p --replay-times 3
# 重新执行某INDEX的调用 限制调用3次 指定隔多久调用
tt -i 1008 -p --replay-times 3 --replay-interval 2000
作用:全局开关
# 显示所有类型
options
# 查看具体某个选项
options json-format
# 设置
options save-result true
# 启动火焰图
profiler start
# 获得样板
profiler getSamples
# 查看获取的状态
profiler status
# 停止(生成火焰图)
profiler stop
# 输出html的火焰图
profiler stop --format html
# 查看支持的事件
profiler list
apt-get update
apt install curl
下载地址:https://download.csdn.net/download/Asia1752/59553943
使用方式如下图