JVM 调优 (3) -- 调优工具 Arthas


Arthas 在线学习网站

1. Arthas 安装与启动

Authas 是一款开源的 Java 诊断工具。

我使用的系统是 window。

下载命令:curl -O https://alibaba.github.io/arthas/arthas-boot.jar (可以直接把连接复制到迅雷,下载很快)

使用 Arthas 之前需要保证得有 Java 程序在运行

启动 Arthas,命令:java -jar E:\VMShare\Arthas\arthas-boot.jar
在这里插入图片描述
选择其中一个 Java 进程,这里我选 3,也就是 SystemApplication(这是我项目中的一个 SpringBoot 启动类)
在这里插入图片描述
到这里就登陆成功,可以使用 Arthas 了。

2. Arthas 参数的使用

1. help

help:查看可以使用的命令和各个命令的描述。
在这里插入图片描述
Arthas 里每一个命令都有详细的帮助信息。可以用 -h 来查看。帮助信息里有 EXAMPLES 和 WIKI 链接。如:sysprop -h
在这里插入图片描述

2. 一些基本命令

  1. cls:清屏命令,相当于我们平时 Linux 中使用的 clear,window 系统的清屏命令也是 cls。
  2. pwd:返回当前的工作目录,和linux命令类似。
    在这里插入图片描述
  3. cat:打印文件内容,和 Linux 里的 cat 命令类似,因为工作目录是 D:\IDEA_CODE\ihrm_parent,所以这里直接 cat pom.xml,也就是打印 D:\IDEA_CODE\ihrm_parent\pom.xml的内容。
    在这里插入图片描述
  4. session:查看当前会话的信息。
    在这里插入图片描述
  5. reset:重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类。
  6. version:输出当前目标 Java 进程所加载的 Arthas 版本号。
  7. quit、exit:退出当前 Arthas 客户端,其他 Arthas 客户端不受影响。
  8. stop:关闭 Arthas 服务端,所有 Arthas 客户端全部退出。

3. history

history:可以查看自己之前使用过的命令
在这里插入图片描述
还可以使用管道来过滤,如:history | grep sys
在这里插入图片描述

4. dashboard

dashboard:查看当前系统的实时数据面板,会显示出线程 (按照 CPU 占用百分比倒排)、内存(堆空间实时情况)、GC 情况等数据,输入 Q 或者 Ctrl+C 可以退出 dashboard 命令。
在这里插入图片描述
常用的参数:

  1. -i:每次执行间隔时间,如:dashboard -i 1000
  2. -n:执行多少次 dashboard,不指定的话会一直刷新,如:dashboard -n 2

5. thread

thread:查看当前 JVM 中的线程信息的。
在这里插入图片描述
thread 后可以加上线程 ID,表示打印线程 ID 为 n 的线程的堆栈信息,Arthas 支持管道,可以用 thread n | grep 'main(' 查找到 main class。
在这里插入图片描述
常用参数:

  1. -b:查看目前 block 的线程,如:thread -b
  2. -i:查看在接下来的多长时间内统计 CPU 利用率,如:thread -i 1000
  3. -n:查看 CPU 占用率前几的线程的堆栈信息,如:thread -n 2
    在这里插入图片描述

6. sc

即 Search class
sc:查找所有 JVM 里已加载的类,如果搜索的是接口,还会搜索所有的实现类,sc 还支持通配符 *
在这里插入图片描述
通过 -d 参数,可以打印出类加载的具体信息,很方便查找类加载问题,如:sc -d *UserController
在这里插入图片描述
通过 sc -h 可以查看更多命令

7. sm

即 search method
sm:查找对应类的所有方法。

  1. 查找类的具体函数。比如:sm com.ihrm.system.controller.UserController
    在这里插入图片描述
  2. 通过 -d 参数可以打印函数的具体属性:sm -d com.ihrm.system.controller.UserController
    在这里插入图片描述
  3. 也可以查找特定的函数,比如查找构造函数:sm -d com.ihrm.system.controller.UserController <init>
    在这里插入图片描述

8. jad

jad:反编译代码,查找类的具体函数。如:jad com.ihrm.system.controller.UserController
在这里插入图片描述
通过--source-only参数可以只打印出在反编译的源代码:jad --source-only com.ihrm.system.controller.UserController
在这里插入图片描述

9. watch

watch:查看函数的参数/返回值/异常信息,第一个参数是类名,支持通配,第二个参数是函数名,支持通配,如:watch com.ihrm.system.controller.UserController login params,当我在自己项目的登录页面点击登录时 (也就是相应的 login 方法被调用时),arthas 界面打印出下面的数据,输入 Q 或者 Ctrl+C 可以退出 watch 命令
在这里插入图片描述

  1. 第三个参数是返回值表达式,它实际上是一个 ognl 表达式,它支持一些内置对象:
    1. loader:本次调用类所在的 ClassLoader
    2. clazz:本次调用类的 Class 引用
    3. method:本次调用方法反射引用
    4. target:本次调用类的实例
    5. params:本次调用参数列表,这是一个数组,如果方法是无参方法则为空数组
    6. returnObj:本次调用返回的对象。当且仅当 isReturn==true 成立时候有效,表明方法调用是以正常返回的方式结束。如果当前方法无返回值 void,则值为 null
    7. throwExp:本次调用抛出的异常。当且仅当 isThrow==true 成立时有效,表明方法调用是以抛出异常的方式结束
    8. isBefore:辅助判断标记,当前的通知节点有可能是在方法一开始就通知,此时 isBefore==true 成立,同时 isThrow==false 和 isReturn==false,因为在方法刚开始时,还无法确定方法调用将会如何结束
    9. isThrow:辅助判断标记,当前的方法调用以抛异常的形式结束
    10. isReturn:辅助判断标记,当前的方法调用以正常返回的形式结束。
      在这里插入图片描述
  2. 你可以利用这些内置对象来组成不同的表达式。比如返回一个数组:watch com.ihrm.system.controller.UserController * '{params[0], target, returnObj}',点击我的项目界面上的登录按钮
    在这里插入图片描述
  3. 条件表达式:watch 命令支持在第 4 个参数里写条件表达式,比如:watch com.example.demo.arthas.user.UserController * returnObj 'params[0] > 100'
    在这里插入图片描述
  4. 当异常捕获时,watch 命令支持 -e 选项,表示只捕获抛出异常时的请求:watch com.example.demo.arthas.user.UserController * "{params[0],throwExp}" -e
  5. 按照耗时进行过滤:watch 命令支持按请求耗时进行过滤,比如:watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'

10.Tab 键

Tab 键:自动补全,很多地方都能用。
在这里插入图片描述

11. sysprop

sysprop:打印所有的 System Properties 信息

  1. 也可以指定单个 key:sysprop java.vendor
    在这里插入图片描述
  2. 也可以通过 grep 来过滤:sysprop | grep vendor
    在这里插入图片描述
  3. 也可以设置新的 value:sysprop testKey testValue
    在这里插入图片描述

12. sysenv

sysenv:获取到环境变量。和 sysprop 命令的用法类似。

13. jvm

jvm:打印出 JVM 的各种详细信息。

14. keymap

Arthas 支持常见的命令行快捷键,比如Ctrl + A跳转行首,Ctrl + E跳转行尾。更多的快捷键可以用 keymap 命令查看。

keymap:Arthas 快捷键列表及自定义快捷键
在这里插入图片描述

15. 支持管道

Arthas 支持在 pipeline 之后,执行一些简单的命令,比如:sysprop | grep javasysprop | wc -l

16. ognl

ognl:在 Arthas 里,有一个单独的 ognl 命令,可以动态执行代码。

  1. 调用 static 函数,如:ognl '@java.lang.System@out.println("hello ognl")',可以检查控制台里的进程输出,发现打印出了 hello ognl。
    在这里插入图片描述
  2. 获取类中的静态字段,如:获取 UserController 类里的 i 字段:ognl @com.ihrm.system.controller.UserController@i
    在这里插入图片描述
  3. 还可以通过 -x 参数控制返回值的展开层数。比如:ognl -c 1be6f5c3 -x 2 @com.ihrm.system.controller.UserController@i
  4. 通过 -c 参数指定类加载器,后面跟 类加载器的 哈希码
  5. 执行多个表达式,赋值给临时变量,返回一个 List,ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
    在这里插入图片描述
  6. 在 Arthas 里 ognl 表达式是很重要的功能,在很多命令里都可以使用 ognl 表达式。OGNL特殊用法请参考OGNL表达式官方指南

17. monitor

monitor:是一个非实时返回命令,实时返回命令是输入之后立即返回,而非实时返回的命令,则是不断的等待目标 Java 进程返回信息,直到用户输入 Ctrl+C 或者 Q 为止。
服务端是以任务的形式在后台跑任务,植入的代码随着任务的中止而不会被执行,所以任务关闭后,不会对原有性能产生太大影响,而且原则上,任何Arthas命令不会引起原有业务逻辑的改变。

监控的维度说明:
在这里插入图片描述
在这里插入图片描述

18. classloader

查看 classloader 的继承树,urls,类加载信息。

参数:

  1. -t :把 classloader 的树打印出来,也会打印出来粗略的 hashcode
    在这里插入图片描述
  2. -l :根据 classloader 实例的个数来打印 classloader,会打印出来 hashcode,如:classloader -l
  3. -c :用 classloader 对应的 hashcode 来查看对应的 jar urls,如:classloader -c 123772c4
  4. 也可以尝试查找类的class文件:classloader -c 123772c4 -r java/lang/String.class
  5. 使用 classloader 去加载类,如:classloader -c 123772c4 --load demo.MathGame

19. trace

trace:方法内部调用路径,并输出方法路径上的每个节点上耗时。

平时主要使用 -j (忽略 jdk method trace)、’#cost>10’(过滤耗时时间) -n (执行次数):
在这里插入图片描述

20. stack

stack:输出当前方法被调用的调用路径,很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。

主要使用 -n 命令,用于控制执行次数:
在这里插入图片描述

21. tt

在这里插入图片描述
字段说明:

  1. INDEX:时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要。
  2. TIMESTAMP:方法执行的本地时间,记录了这个时间片段所发生的本地时间。
  3. COST(ms):方法执行的耗时
  4. IS-RET:方法是否以正常返回的形式结束
  5. IS-EXP:方法是否以抛异常的形式结束
  6. OBJECT:执行对象的 hashCode(),注意,曾经有人误认为是对象在 JVM 中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体
  7. CLASS:执行的类名
  8. METHOD:执行的方法名

注意:

  1. tt 命令有很多个主参数,-t 就是其中之一。这个参数的表明希望记录下例如类 *Test 的 print 方法的每次执行情况。
  2. 当你执行一个调用量不高的方法时可能你还能有足够的时间用 CTRL+C 中断 tt 命令记录的过程,但如果遇到调用量非常大的方法,瞬间就能将你的 JVM 内存撑爆。此时你可以通过 -n 参数指定你需要记录的次数,当达到记录次数时 Arthas 会主动中断 tt 命令的记录过程,避免人工操作无法停止的情况。
  3. 当你用 tt 记录了一大片的时间片段之后,你希望能从中筛选出自己需要的时间片段,这个时候你就需要对现有记录进行检索。你需要一个 -s 参数。同样的,搜索表达式的核心对象依旧是 Advice 对象。
    在这里插入图片描述
  4. 对于具体一个时间片的信息而言,你可以通过 -i 参数后边跟着对应的 INDEX 编号查看到他的详细信息。
    在这里插入图片描述
  5. 当你稍稍做了一些调整之后,你可能需要前端系统重新触发一次你的调用,此时需要前端配合联调的同学再次发起一次调用。而有些场景下,这个调用不是这么好触发的。tt 命令由于保存了当时调用的所有现场信息,所以我们可以自己主动对一个 INDEX 编号的时间片自主发起一次调用,从而解放你的沟通成本。此时你需要 -p 参数。通过 --replay-times 指定调用次数,通过 --replay-interval 指定多次调用间隔(单位ms, 默认1000ms)
    在这里插入图片描述
    你会发现结果虽然一样,但调用的路径发生了变化,有原来的程序发起变成了 Arthas 自己的内部线程发起的调用了。
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值