《Arthas》--问题定位神器--常用指令一图全知

阿丹:

        因为一个图太大,直接放出来影响观看,我给他们分开来。 

图中关键标识:

 基础命令:

 class相关

 

 

 

 

 

 

jvm相关

 

 

 

 

 

 

 

 

 

 

字节码增强

 

 

 

 

  • ArtHas

    • 基础命令

      • help 查看命令帮助信息

      • cls 清空当前屏幕区域

      • session 查看当前会话的信息

      • reset 重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类

      • version 输出当前目标 Java 进程所加载的 Arthas 版本号

      • history 打印命令历史

      • quit 退出当前 Arthas 客户端,其他 Arthas 客户端不受影响

      • stop 和shutdown命令一致

      • shutdown 关闭 Arthas 服务端,所有 Arthas 客户端全部退出

      • keymap Arthas快捷键列表及自定义快捷键

      • options 查看或设置Arthas全局开关

    • class相关

      • sc

        • 作用

          • 查看JVM已加载的类信息

        • 参数

          • 参数表

              • <class-pattern>

              • 类名表达式匹配

              • sc demo.*

              • -x, --expand <value>

              • 展开层次

              • -E, --regex

              • 开启正则表达式

              • sc -E org\\.apache\\.commons\\.lang\\.StringUtils

              • -d, --details

              • 显示详细信息

              • -f, --field

              • 输出当前类的成员变量信息(需要配合参数-d一起使用)

              • sc -d -f demo.MathGame

      • sm

        • 作用

          • “Search-Method” 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。

        • 参数

          • 参数表

              • <class-pattern>

              • 类名表达式匹配

              • sm java.lang.String

              • -E, --regex

              • 开启正则表达式

              • sm -Ed org\\.apache\\.commons\\.lang\.StringUtils .*

              • -d, --details

              • 显示详细信息,配合方法名使用

              • sm -d java.lang.String toString

      • jad

        • 作用

          • 反编译指定已加载类的源码

        • 示例

          • 反编绎时只显示源代码

            • jad --source-only demo.MathGame

          • 反编译指定类

            • jad java.lang.String

          • 反编译指定的函数

            • jad demo.MathGame main

          • 反编译时指定ClassLoader

            • jad org.apache.log4j.Logger

            • jad org.apache.log4j.Logger -c 69dcaba4

      • mc

        • 作用

          • Memory Compiler/内存编译器,编译.java文件生成.class

        • 基本不用

      • redefine

        • 作用

          • 加载外部的.class文件,redefine jvm已加载的类

        • 参数

          • -c

            • ClassLoader的hashcode

              • redefine -c 327a647b /tmp/Test.class /tmp/Test\$Inner.class

          • -p

            • 外部的.class文件的完整路径,支持多个

              • redefine /tmp/Test.class

        • 组合用法

          • jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java

          • mc /tmp/UserController.java -d /tmp

          • redefine /tmp/com/example/demo/arthas/user/UserController.class

        • 限制

          • 不允许新增加field/method

          • 正在跑的函数,没有退出不能生效,比如下面新增加的System.out.println,只有run()函数里的会生效

      • dump

        • 作用

          • dump 已加载类的 bytecode 到特定目录

        • 使用参考

          • dump java.lang.String

          • dump demo.*

      • classloader

        • 作用

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

        • 参数

          • -a, --all

            • 列出所有ClassLoader加载的类,请谨慎使用

          • -c, --classloader <value>

            • ClassLoader的hashcode,查看URLClassLoader实际的urls

              • classloader -c 3d4eac69

          • -h, --help this help

          • -i, --include-reflection-classloader

          • -l, --list-classloader

            • 按类加载实例进行统计

              • classloader -l

          • --load <value>

            • 用ClassLoader去加载指定的类,配合-c

              • classloader -c 3d4eac69 --load demo.MathGame

          • -r, --resource <value>

            • 用ClassLoader去查找resource 配合-c

              • classloader -c 3d4eac69 -r META-INF/MANIFEST.MF

              • classloader -c 1b6d3586 -r java/lang/String.class

          • -t, --tree

            • 打印所有ClassLoader的继承树

              • classloader -t

    • jvm相关

      • dashboard

        • 作用

          • 当前系统的实时数据面板

        • 说明

        • 面板

      • thread

        • 作用

          • 查看当前线程信息,查看线程的堆栈

        • 参数

          • 参数表

              • -n, --top-n-threads <value>

              • 指定最忙的前N个线程并打印堆栈

              • thread -n 5

              • -i, --sample-interval <value>

              • 指定cpu占比统计的采样间隔,单位为毫秒

              • thread -i 2000

              • -b, --include-blocking-thread

              • 找出当前阻塞其他线程的线程

              • stack *StringUtils isBlank '#cost>100'

              • 线程id

              • 显示线程信息

              • thread 1

      • jvm

        • 作用

          • 查看当前JVM信息

        • 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)

        • 参数

          • 参数表

              • 查看所有

              • sysprop

              • <property-name>

              • 查看单个属性,支持补全

              • sysprop java.version

              • <property-value>

              • 修改单个属性

              • sysprop user.country CN

      • sysenv

        • 作用

          • 查看当前JVM的环境属性(System Environment Variables)

        • 参数

          • 参数表

              • 查看所有

              • sysenv

              • <env-name>

              • 查看单个环境变量

              • sysenv USER

      • vmoption

        • 作用

          • 查看,更新VM诊断相关的参数

        • 使用

          • 查看所有的option

            • vmoption

          • 查看指定的option

            • vmoption PrintGCDetails

          • 更新指定的option

            • vmoption PrintGCDetails true

      • logger

        • 作用

          • 查看logger信息,更新logger level

        • 使用

          • 查看logger配置信息

            • logger

          • 查看指定名字的logger信息

            • logger -n org.springframework.web

          • 查看指定classloader的logger信息

            • logger -c 2a139a55

          • 更新logger level

            • logger --name ROOT --level debug

          • 查看没有appender的logger的信息

            • logger --include-no-appender

      • getstatic

        • 用例

          • getstatic com.alibaba.arthas.Test n 'entrySet().iterator.{? #this.key.name()=="STOP"}'

        • 作用

          • 访问静态变量

        • 推荐直接使用ognl命令,更加灵活。

      • ognl

        • 作用

          • 执行ognl表达式

        • 参数

          • 指定类加载器

            • -c classloader

          • 指定展开级别

            • -x extend

        • 使用示例

          • 调用静态属性

            • ognl '@全路径类目@静态属性名'

              • ognl '@com.shirc.arthasexample.ognl.OgnlTest@static_str'

          • 调用静态方法

            • ognl '@全路径类目@静态方法名("参数")'

              • 简单入参 返回普通对象

                • ognl '@com.shirc.arthasexample.ognl.OgnlTest@getPerson("src",18)' -X 1

              • 简单入参 返回对象中包含对象和List

                • ognl '@com.shirc.arthasexample.ognl.OgnlTest@getPerson("src",18,2)' -x 1

              • 方法A的返回值当做方法B的入参

                • ognl '#value1=@com.shirc.arthasexample.ognl.OgnlTest@getPerson("src",18), #value2=@com.shirc.arthasexample.ognl.OgnlTest@setPerson(#value1) ,{#value1,#value2}' -x 2

              • 执行多行表达式,赋值给临时变量,返回一个List:

                • ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'

              • 方法入参是简单类型列表

                • ognl '@com.shirc.arthasexample.ognl.OgnlTest@getChilds({"jinjidelaomanong","jjdlmn"})' -x 2

              • 方法入参是一个复杂对象

                • ognl '#obj=new com.shirc.arthasexample.ognl.Shirc("jjdlmn",true),@com.shirc.arthasexample.ognl.OgnlTest@inputObj(#obj)' -x 2

              • 方法入参是一个Map对象

                • ognl '#inputmap=#{ "foo" : "foo value", "bar" : "bar value" }, @com.shirc.arthasexample.ognl.OgnlTest@getMap(#inputmap)' -x 2

          • 读取不同类型的值

            • 访问复杂对象属性

              • ognl '@com.shirc.arthasexample.ognl.OgnlTest@getPerson("src",18).name' -x 4

            • 访问List或者数组类型

              • ognl '@com.shirc.arthasexample.ognl.OgnlTest@getChilds({"jinjidelaomanong","jjdlmn"})[0]' -x 2

            • 访问Map对象

              • ognl '@com.shirc.arthasexample.ognl.OgnlTest@getMap()["shirc"]' -x 2

              • ognl '@com.shirc.arthasexample.ognl.OgnlTest@getMap()["shirc"].sex' -x 2

        • 高级操作

          • 投影(Across)

            • 在投影中调用方法

              • watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{#this.convert()}'

            • 简单示例

              • watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{#this.username}' -b -x 2

            • 在观察表达式里过滤

              • watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{? #this.id > 8}' -b -x 2

            • 过滤后计数

              • watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{? #this.username.endsWith("9")}.size()'

            • 子表达式计算

              • watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].size().(#this>5? 20+#this:10+#this)'

        • 说明

          • #变量引用 #this 当前对象

            • OGNL的变量方案很简单, 你可以用变量来保存中间结果, 并在后面的代码中再次访问它, 也可以用变量来使整个表达式更加简单易懂. OGNL中的所有变量, 对整个表达式都是全局可见的. 引用变量的方法是在变量名之前加上 # 号

            • OGNL在计算表达式的过程中, 随时会将当前对象保存在 "this"变量中, 这个变量也可以象其他任何变量一样引用,用 #this 表示当前对象

          • 用例

            • ognl '@com.shirc.arthasexample.ognl.OgnlTest@getMap()["shirc"].(#this.sex=="boy"?"BoyNB":"GirlNB")' -x 2

      • mbean

        • 作用

          • 这个命令可以便捷的查看或监控 Mbean 的属性信息。

        • 参数

          • 参数表

              • <name-pattern>不填该项查看所有

              • 名称匹配,详见javax.management.ObjectName

              • mbean org.opendaylight.controller:type=RemoteRp*,name=*

              • <attribute-pattern>

              • 属性匹配,查看mxbean的某个属性

              • mbean org.opendaylight.controller:type=RemoteRp*,name=* Globa*

              • -n, --number-of-execution <value>

              • 刷新属性值的次数

              • -E, --regex

              • 开启正则表达式

              • mbean -E java.lang:type=Threading PeakThreadCount|ThreadCount|DaemonThreadCount

              • -i, --interval <value>

              • 刷新属性值的时间间隔 (ms)

              • mbean -i 1000 org.opendaylight.controller:type=RemoteRp*,name=*

            • 子主题 6

              • -m, --metadata

              • 显示mbean的元数据

        • 说明

      • heapdump

        • 作用

          • dump java heap, 类似jmap命令的heap dump功能

        • 使用

          • dump到指定文件

            • heapdump /tmp/dump.hprof

          • 只dump live对象

            • heapdump --live /tmp/dump.hprof

          • dump到临时文件

            • heapdump

    • 字节码增强

      • tt

        • 作用

          • 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测

        • 与watch对比

          • watch 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。 这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。

        • 参数

          • <class-pattern> <method-pattern>

            • 类名 + 方法名 配合-t使用

            • tt -t *Test print 'params[1] instanceof Integer'

          • <condition-express>

            • 条件表达式,可以通过条件表达式解决重载问题

            • tt -t demo.MathGame primeFactors 'params.length>=0'

          • -t, --time-tunnel

            • 记录方法的执行时间碎片

          • -d --delete

            • 根据index删除,和-i配合使用

            • tt -d -i 1064

          • --delete-all

            • 删除所有

          • -x <value>

            • 指定输出结果的属性遍历深度,默认为1

            • -x 3

          • -h

            • 帮助信息

          • -i, --index <value>

            • 显示一个时间片段的详细信息

            • tt -i 5

          • -n, --limits <value>

            • 设置执行次数,不然多次调用的方法可能会内存溢出

          • -l, --list

            • 展示所有时间片段

          • -p, --play

            • 重新执行某个时间片段,和-i配合使用

            • tt -i 5 -p

          • -E, --regex

            • 开启正则表达式匹配,默认为通配符匹配

          • --replay-interval <value>

            • 执行多次时间间隔,和-p与--replay-interval <value>配合使用

          • --replay-times <value>

            • 执行多次,和-p配合使用

            • tt -i 1067 -p --replay-interval 1000 --replay-times 3

          • -s, --search-express <value>

            • 通过OGNL表达式进行查找,支持advice

            • tt -s 'method.name=="primeFactors"'

          • -M, --sizeLimit <value>

            • 指定结果的字节数组上限,默认10*1024*1024bytes

          • -w, --watch-express <value>

            • 通过ognl表达式查看time fragments(时间碎片)

            • tt -i 1067 -w params[0]

            • tt -i 1067 -w '{params[0], target, returnObj}'

        • 字段解析

        • 注意事项

          • ThreadLocal 信息丢失

            • 很多框架偷偷的将一些环境变量信息塞到了发起调用线程的 ThreadLocal 中,由于调用线程发生了变化,这些 ThreadLocal 线程信息无法通过 Arthas 保存,所以这些信息将会丢失。 一些常见的 CASE 比如:鹰眼的 TraceId 等。

          • 引用的对象

            • 需要强调的是,tt 命令是将当前环境的对象引用保存起来,但仅仅也只能保存一个引用而已。如果方法内部对入参进行了变更,或者返回的对象经过了后续的处理,那么在 tt 查看的时候将无法看到当时最准确的值。这也是为什么 watch 命令存在的意义。

      • watch

        • 作用

          • 让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 OGNL 表达式进行对应变量的查看。

        • 参数

          • 参数表

              • <class-pattern>

              • 类名表达式匹配

              • <method-pattern>

              • 你想要观察的方法

              • watch demo.MathGame primeFactors throwExp

              • <express>

              • 观察表达式,你想观察什么 OGNL表达式

              • watch demo.MathGame primeFactors '{params[0], target, returnObj}'

              • <condition-express>

              • 条件表达式,符合条件的观察(boolean)

              • watch demo.MathGame primeFactors params 'params.length>=0'

              • -b, --before

              • 在方法调用之前观察

              • -s, --success

              • 方法成功执行后观察

              • watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2

              • -e, --exception

              • 在方法异常之后观察

              • watch demo.MathGame primeFactors throwExp -e

              • -f, --finish

              • 在方法结束之后观察,包括正常异常场景(默认)

              • -x, --expand <value>

              • 指定输出结果的属性遍历深度,默认为 1

              • -n, --limits <value>

              • 观察的次数

              • -E, --regex

              • 开启正则表达式

              • -M, --sizeLimit <value>

              • 指定结果的字节数组上限,默认10*1024*1024bytes

        • 特别说明

          • watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后

          • 4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出

          • 这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参

          • 当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在

      • monitor

        • 作用

          • 方法执行监控

          • 对匹配 class-pattern/method-pattern的类、方法的调用进行监控。

        • 参数

          • 参数表

              • <class-pattern>

              • 类名表达式匹配

              • <method-pattern>

              • 你想要监视的方法

              • monitor org.apache.commons.lang.StringUtils isBlank

              • -c, --cycle <value>

              • 监视周期 默认60s

              • monitor -c 5 demo.MathGame primeFactors

              • -n, --limits <value>

              • 监视几个周期

              • -E, --regex

              • 开启正则表达式

        • 说明

          • monitor 命令是一个非实时返回命令

        • 监控的维度

      • stack

        • 作用

          • 输出当前方法被调用的调用路径

        • 说明

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

        • 参数

          • 参数表

              • <class-pattern>

              • 类名表达式匹配

              • <method-pattern>

              • 你想要监视的方法

              • stack demo.MathGame primeFactors

              • -n, --limits <value>

              • 监视几个周期

              • stack demo.MathGame primeFactors 'params[0]<0' -n 2

              • -E, --regex

              • 开启正则表达式

              • stack -E org\.apache\.commons\.lang\.StringUtils isBlank

              • <condition-express>

              • 条件表达式,支持#cost

              • stack *StringUtils isBlank '#cost>100'

      • trace

        • 作用

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

        • 参数

          • 参数表

              • <class-pattern>

              • 类名表达式匹配

              • <method-pattern>

              • 你想要监视的方法

              • trace demo.MathGame run

              • -j, --jdkMethodSkip

              • 跳过jvm方法

              • trace demo.MathGame run -j

              • -n, --limits <value>

              • 监视几个周期

              • -E, --regex

              • 开启正则表达式

              • trace -E com.test.ClassA|org.test.ClassB method1|method2|method3

              • <condition-express>

              • 条件表达式,支持#cost

              • trace *StringUtils isBlank '#cost>100'

        • 重要说明

          • 很多时候我们只想看到某个方法的rt大于某个时间之后的trace结果,现在Arthas可以按照方法执行的耗时来进行过滤了,例如trace *StringUtils isBlank '#cost>100'表示当执行时间超过100ms的时候,才会输出trace的结果。

          • watch/stack/trace这个三个命令都支持#cost

        • 注意

          • trace 能方便的帮助你定位和发现因 RT 高而导致的性能问题缺陷,但其每次只能跟踪一级方法的调用链路。

          • trace命令只会trace匹配到的函数里的子调用,并不会向下trace多层。因为trace是代价比较贵的,多层trace可能会导致最终要trace的类和函数非常多。

          • 可以用正则表匹配路径上的多个类和函数,一定程度上达到多层trace的效果。

            • trace -E com.test.ClassA|org.test.ClassB method1|method2|method3

 

  • 23
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值