1. Arthas官网
arthas
2. 下载
从 Maven 仓库下载
最新版本,点击下载:编辑在新窗口打开
点击这个 mavrn-central 即可显示下面的图片
#从 Github Releases 页下载
Releases · alibaba/arthas · GitHub
3. 解压
将压缩包复制到一个位置,解压
4. 启动
用 arthas-boot 启动
或者在解压后,在文件夹里有arthas-boot.jar
,直接用java -jar
的方式启动:
java -jar arthas-boot.jar
打印帮助信息:
java -jar arthas-boot.jar -h
遇到问题可以参考:https://blog.csdn.net/qq_16313575/article/details/136206191?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22136206191%22%2C%22source%22%3A%22qq_16313575%22%7D
Video_2024-02-21_134454
服务器运行:
先将对应的arthas程序下载到本地,可以使用wget
命令,也可以使用官网介绍的curl
访问对应链接
wget https://arthas.aliyun.com/arthas-boot.jar
然后安装文档,启动对应的jar
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
5. 命令
5.1 jad
jad-反编译指定已加载类的源码
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
[c:] | 类所属 ClassLoader 的 hashcode |
[classLoaderClass:] | 指定执行表达式的 ClassLoader 的 class name |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
反编译时只显示源代码
默认情况下,反编译结果里会带有ClassLoader
信息,通过--source-only
选项,可以只打印源代码。方便和mc/retransform命令结合使用。
$ jad --source-only demo.MathGame
/*
* Decompiled with CFR 0_132.
*/
package demo;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class MathGame {
private static Random random = new Random();
public int illegalArgumentCount = 0;
...
反编译指定的函数
$ jad demo.MathGame main
ClassLoader:
+-sun.misc.Launcher$AppClassLoader@232204a1
+-sun.misc.Launcher$ExtClassLoader@7f31245a
Location:
/private/tmp/math-game.jar
public static void main(String[] args) throws InterruptedException {
MathGame game = new MathGame();
while (true) {
/*16*/ game.run();
/*17*/ TimeUnit.SECONDS.sleep(1L);
}
}
反编译时不显示行号
--lineNumber
参数默认值为 true,显示指定为 false 则不打印行号。
$ jad demo.MathGame main --lineNumber false
ClassLoader:
+-sun.misc.Launcher$AppClassLoader@232204a1
+-sun.misc.Launcher$ExtClassLoader@7f31245a
Location:
/private/tmp/math-game.jar
public static void main(String[] args) throws InterruptedException {
MathGame game = new MathGame();
while (true) {
game.run();
TimeUnit.SECONDS.sleep(1L);
}
}
反编译时指定 ClassLoader
提示
当有多个
ClassLoader
都加载了这个类时,jad
命令会输出对应ClassLoader
实例的hashcode
,然后你只需要重新执行jad
命令,并使用参数-c <hashcode>
就可以反编译指定 ClassLoader 加载的那个类了;
$ 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.
$ 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.
对于只有唯一实例的 ClassLoader 还可以通过--classLoaderClass
指定 class name,使用起来更加方便:
--classLoaderClass
的值是 ClassLoader 的类名,只有匹配到唯一的 ClassLoader 实例时才能工作,目的是方便输入通用命令,而-c <hashcode>
是动态变化的。
5.2 thread
thread-查看当前JVM的线程堆栈信息
参数名称 | 参数说明 |
---|---|
id | 线程 id |
[n:] | 指定最忙的前 N 个线程并打印堆栈 |
[b] | 找出当前阻塞其他线程的线程 |
[i <value> ] | 指定 cpu 使用率统计的采样间隔,单位为毫秒,默认值为 200 |
[--all] | 显示所有匹配的线程 |
查看帮助文档
支持一键展示当前最忙的前 N 个线程并打印堆栈:
$ thread -n 3
- 没有线程 ID,包含
[Internal]
表示为 JVM 内部线程,参考dashboard命令的介绍。 cpuUsage
为采样间隔时间内线程的 CPU 使用率,与dashboard命令的数据一致。deltaTime
为采样间隔时间内线程的增量 CPU 时间,小于 1ms 时被取整显示为 0ms。time
线程运行总 CPU 时间。
注意:线程栈为第二采样结束时获取,不能表明采样间隔时间内该线程都是在处理相同的任务。建议间隔时间不要太长,可能间隔时间越大越不准确。 可以根据具体情况尝试指定不同的间隔时间,观察输出结果。
当没有参数时,显示第一页线程的信息
默认按照 CPU 增量时间降序排列,只显示第一页数据。
$ thread
thread --all, 显示所有匹配的线程
显示所有匹配线程信息,有时需要获取全部 JVM 的线程数据进行分析。
thread id, 显示指定线程的运行堆栈
$ thread 1
thread -b, 找出当前阻塞其他线程的线程
有时候我们发现应用卡住了, 通常是由于某个线程拿住了某个锁, 并且其他线程都在等待这把锁造成的。 为了排查这类问题, arthas 提供了thread -b
, 一键找出那个罪魁祸首。
$ thread -b
注意
注意, 目前只支持找出 synchronized 关键字阻塞住的线程, 如果是java.util.concurrent.Lock
, 目前还不支持。
thread -i, 指定采样时间间隔
-
thread -i 1000
: 统计最近 1000ms 内的线程 CPU 时间。 -
thread -n 3 -i 1000
: 列出 1000ms 内最忙的 3 个线程栈
$ thread -n 3 -i 1000
thread --state ,查看指定状态的线程
$ thread --state WAITING
5.3 trace
trace-方法内部调用路径,并输出方法路径上的每个节点上耗时
trace
命令能主动搜索 class-pattern
/method-pattern
对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
condition-express | 条件表达式 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[n:] | 命令执行次数 |
#cost | 方法执行耗时 |
[m <arg>] | 指定 Class 最大匹配数量,默认值为 50。长格式为[maxMatch <arg>] 。 |
trace 函数
$ trace demo.MathGame run
指定 Class 匹配的最大数量
$ trace demo.MathGame run -m 1
trace 次数限制
$ trace demo.MathGame run -n 1
根据调用耗时过滤
$ trace demo.MathGame run '#cost > 10'
5.4 watch
watch-方法执行数据观测
相当于Debug
让你能方便的观察到指定函数的调用情况。能观察到的范围为:返回值
、抛出异常
、入参
,通过编写 OGNL 表达式进行对应变量的查看。
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 函数名表达式匹配 |
express | 观察表达式,默认值:{params, target, returnObj} |
condition-express | 条件表达式 |
[b] | 在函数调用之前观察 |
[e] | 在函数异常之后观察 |
[s] | 在函数返回之后观察 |
[f] | 在函数结束之后(正常返回和异常返回)观察 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[x:] | 指定输出结果的属性遍历深度,默认为 1,最大值是 4 |
[m <arg>] | 指定 Class 最大匹配数量,默认值为 50。长格式为[maxMatch <arg>] 。 |
5.5 tt
tt-方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
重放请求
idea安装的插件:
阿里的Arthas真的太好用了
阿里的Arthas真的太好用了_哔哩哔哩_bilibili