1、基础命令
- version 查看当前arthas版本
- history 历史命令
- quit 退出
- cat 查看命令
- echo 输出
- grep 管道命令
- pwd 输出当前目录
- options 全局开关
- session 查看当前session信息
2、系统命令
- dashboard 实时数据面板
- [i:] 刷新实时数据的时间间隔 (ms),默认5000ms
- [n:] 刷新实时数据的次数
[arthas@17]$ dashboard
ID NAME GROUP PRIORIT STATE %CPU DELTA_T TIME INTERRUP DAEMON
-1 C1 CompilerThread0 - -1 - 0.0 0.000 0:2.102 false true
-1 C2 CompilerThread0 - -1 - 0.0 0.000 0:2.089 false true
-1 VM Periodic Task Thread - -1 - 0.0 0.000 0:1.522 false true
1 main main 5 TIMED_W 0.0 0.000 0:0.883 false false
24 arthas-command-execute system 5 RUNNABL 0.0 0.000 0:0.836 false true
23 arthas-NettyHttpTelnetBo system 5 RUNNABL 0.0 0.000 0:0.570 false true
-1 VM Thread - -1 - 0.0 0.000 0:0.335 false true
11 Attach Listener system 9 RUNNABL 0.0 0.000 0:0.040 false true
-1 Sweeper thread - -1 - 0.0 0.000 0:0.032 false true
16 arthas-NettyHttpTelnetBo system 5 RUNNABL 0.0 0.000 0:0.029 false true
19 arthas-shell-server system 9 TIMED_W 0.0 0.000 0:0.013 false true
Memory used total max usage GC
heap 27M 45M 177M 15.31% gc.copy.count 23
tenured_gen 22M 30M 122M 18.73% gc.copy.time(ms) 145
eden_space 4M 12M 49M 8.35% 2
survivor_space 159K 1536K 6272K 2.55% gc.marksweepcompact.time 41
nonheap 34M 38M -1 90.13% (ms)
codeheap_'non-nmetho 1M 2M 5M 22.14%
ds'
Runtime
os.name Linux
os.version 5.4.0-80-generic
java.version 15-ea
- thread 查看当前线程信息,查看线程的堆栈
- id 线程id
- [n:] 指定最忙的前N个线程并打印堆栈
- [b] 找出当前阻塞其他线程的线程
- [i
] 指定cpu使用率统计的采样间隔,单位为毫秒,默认值为200 - [–all] 显示所有匹配的线程
1)查看线程1的信息
[arthas@17]$ thread 1
"main" Id=1 TIMED_WAITING
at java.base@15-ea/java.lang.Thread.sleep(Native Method)
at java.base@15-ea/java.lang.Thread.sleep(Thread.java:337)
at java.base@15-ea/java.util.concurrent.TimeUnit.sleep(TimeUnit.java:446)
at app//demo.MathGame.main(Unknown Source)
2)查看线程cpu使用率最高的前3个线程
[arthas@17]$ thread -n 3
"arthas-command-execute" Id=24 cpuUsage=0.29% deltaTime=0ms time=799ms RUNNABLE
at java.management@15-ea/sun.management.ThreadImpl.dumpThreads0(Native Method)
at java.management@15-ea/sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:485)
at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:206)
at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:122)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:385)
at java.base@15-ea/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base@15-ea/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base@15-ea/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base@15-ea/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base@15-ea/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base@15-ea/java.lang.Thread.run(Thread.java:832)
"VM Periodic Task Thread" [Internal] cpuUsage=0.05% deltaTime=0ms time=1237ms
"C1 CompilerThread0" [Internal] cpuUsage=0.04% deltaTime=0ms time=2026ms
3)查看线程状态是TIMED_WAITING的线程
[arthas@17]$ thread -state TIMED_WAITING
Threads Total: 16, NEW: 0, RUNNABLE: 9, BLOCKED: 0, WAITING: 3, TIMED_WAITING: 4, TERMINATED: 0
ID NAME GROUP PRIORIT STATE %CPU DELTA_T TIME INTERRUP DAEMON
1 main main 5 TIMED_W 0.06 0.000 0:0.791 false false
19 arthas-shell-server system 9 TIMED_W 0.0 0.000 0:0.011 false true
20 arthas-session-manager system 9 TIMED_W 0.0 0.000 0:0.008 false true
10 Common-Cleaner InnocuousThr 8 TIMED_W 0.0 0.000 0:0.005 false true
- jvm 查看当前JVM信息
[arthas@17]$ jvm
RUNTIME
----------------------------------------------------------------------------------------------------
MACHINE-NAME 17@0f5a896167a1
JVM-START-TIME 2022-01-28 15:28:23
MANAGEMENT-SPEC-VERSION 3.0
SPEC-NAME Java Virtual Machine Specification
SPEC-VENDOR Oracle Corporation
SPEC-VERSION 15
VM-NAME OpenJDK 64-Bit Server VM
VM-VENDOR Oracle Corporation
VM-VERSION 15-ea+8-219
INPUT-ARGUMENTS []
CLASS-PATH math-game.jar
BOOT-CLASS-PATH
LIBRARY-PATH /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
----------------------------------------------------------------------------------------------------
CLASS-LOADING
----------------------------------------------------------------------------------------------------
LOADED-CLASS-COUNT 5408
TOTAL-LOADED-CLASS-COUNT 5408
UNLOADED-CLASS-COUNT 0
IS-VERBOSE false
----------------------------------------------------------------------------------------------------
COMPILATION
----------------------------------------------------------------------------------------------------
NAME HotSpot 64-Bit Tiered Compilers
TOTAL-COMPILE-TIME 3971
[time (ms)]
----------------------------------------------------------------------------------------------------
GARBAGE-COLLECTORS
----------------------------------------------------------------------------------------------------
Copy name : Copy
[count/time (ms)] collectionCount : 23
collectionTime : 145
MarkSweepCompact name : MarkSweepCompact
[count/time (ms)] collectionCount : 2
collectionTime : 41
----------------------------------------------------------------------------------------------------
MEMORY-MANAGERS
----------------------------------------------------------------------------------------------------
CodeCacheManager CodeHeap 'non-nmethods'
CodeHeap 'profiled nmethods'
CodeHeap 'non-profiled nmethods'
Metaspace Manager Metaspace
Compressed Class Space
Copy Eden Space
Survivor Space
MarkSweepCompact Eden Space
Survivor Space
Tenured Gen
----------------------------------------------------------------------------------------------------
MEMORY
----------------------------------------------------------------------------------------------------
HEAP-MEMORY-USAGE init : 12582912(12.0 MiB)
[memory in bytes] used : 27137184(25.9 MiB)
committed : 47243264(45.1 MiB)
max : 186515456(177.9 MiB)
NO-HEAP-MEMORY-USAGE init : 7667712(7.3 MiB)
[memory in bytes] used : 36636728(34.9 MiB)
committed : 40697856(38.8 MiB)
max : -1(-1 B)
PENDING-FINALIZE-COUNT 0
----------------------------------------------------------------------------------------------------
OPERATING-SYSTEM
----------------------------------------------------------------------------------------------------
OS Linux
ARCH amd64
PROCESSORS-COUNT 3
LOAD-AVERAGE 1.81
VERSION 5.4.0-80-generic
----------------------------------------------------------------------------------------------------
THREAD
----------------------------------------------------------------------------------------------------
COUNT 16
DAEMON-COUNT 15
PEAK-COUNT 17
STARTED-COUNT 22
DEADLOCK-COUNT 0
----------------------------------------------------------------------------------------------------
FILE-DESCRIPTOR
----------------------------------------------------------------------------------------------------
MAX-FILE-DESCRIPTOR-COUNT -1
OPEN-FILE-DESCRIPTOR-COUNT -1
- sysprop查看当前JVM的系统属性(System Property)
- sysprop [-h] [property-name] [property-value]
1)查看java属性
[arthas@17]$ sysprop |grep java
java.specification 15
java.runtime.versi 15-ea+8-219
java.class.path math-game.jar
java.vm.vendor Oracle Corporation
java.runtime.name OpenJDK Runtime Environment
java.vendor.url https://java.oracle.com/
java.vm.name OpenJDK 64-Bit Server VM
java.vm.specificat 15
sun.java.launcher SUN_STANDARD
sun.boot.library.p /usr/java/openjdk-15/lib
sun.java.command math-game.jar
java.vendor.url.bu https://bugreport.java.com/bugreport/
java.io.tmpdir /tmp
java.version 15-ea
java.specification Oracle Corporation
java.vm.specificat Java Virtual Machine Specification
java.version.date 2020-09-15
java.home /usr/java/openjdk-15
java.vm.compressed 32-bit
java.library.path /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
java.vm.info mixed mode, sharing
java.vm.specificat Oracle Corporation
java.specification Java Platform API Specification
java.vendor Oracle Corporation
java.vm.version 15-ea+8-219
java.class.version 59.0
2)修改某个属性
$ sysprop user.country
user.country=US
$ sysprop user.country CN
Successfully changed the system property.
user.country=CN
- sysenv查看当前JVM的环境属性(System Environment Variables)
- sysenv [-h] [env-name]
[arthas@17]$ sysenv
KEY VALUE
----------------------------------------------------------------------------------------------------
PATH /usr/java/openjdk-15/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sb
in:/bin:/usr/bin/gradle/bin:/usr/local/bin/scala-2.13.2/bin:/usr/local/bin/sbt
/bin
LESSCLOSE /usr/bin/lesspipe %s %s
SBT_VERSION 1.3.0
JAVA_HOME /usr/java/openjdk-15
TERM xterm
LANG C.UTF-8
PS1 $
GRADLE_HOME /usr/bin/gradle
MAVEN_HOME /usr/share/maven
GRADLE_USER_HOME /cache
JAVA_SHA256 ab41dd4e616e015ec94f26e4d2c8253f376f5f5d574db811f341abc6c55e333c
SCALA_VERSION 2.13.2
JAVA_VERSION 15-ea+8
PWD /root
_ /usr/java/openjdk-15/bin/java
APT_PACKAGES vim man curl software-properties-common unzip zip git netbase zsh tmux curl ma
ke openssh-client netcat netbase ntpdate jq git net-tools iputils-ping wget su
do dnsutils locales iproute2 nano
LANGUAGE en_US:en
LESSOPEN | /usr/bin/lesspipe %s
SHELL /bin/bash
GRADLE_VERSION 6.4.1
MAVEN_CONFIG /root/.m2
HOSTNAME 0f5a896167a1
LC_ALL en_US.UTF-8
DOCKER_VERISON 18.03.1-ce
LESS SXF
LS_COLORS rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;0
1:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=0
HOME /root
SHLVL 1
JAVA_URL https://download.java.net/java/early_access/jdk15/8/GPL/openjdk-15-ea+8_linux-
x64_bin.tar.gz
- vmoption查看,更新VM诊断相关的参数
- vmoption [-h] [name] [value]
1)查看
[arthas@17]$ vmoption
KEY VALUE ORIGIN WRITEABLE
----------------------------------------------------------------------------------------------------
HeapDumpBeforeFullGC false DEFAULT true
HeapDumpAfterFullGC false DEFAULT true
HeapDumpOnOutOfMemoryEr false DEFAULT true
ror
HeapDumpPath DEFAULT true
ShowCodeDetailsInExcept false DEFAULT true
ionMessages
PrintClassHistogram false DEFAULT true
MinHeapFreeRatio 40 DEFAULT true
MaxHeapFreeRatio 70 DEFAULT true
PrintConcurrentLocks false DEFAULT true
G1PeriodicGCInterval 0 DEFAULT true
G1PeriodicGCSystemLoadT 0.0 DEFAULT true
hreshold
SoftMaxHeapSize 192937984 ERGONOMIC true
2)更新
$ vmoption PrintGC true
Successfully updated the vm option.
NAME BEFORE-VALUE AFTER-VALUE
------------------------------------
PrintGC false true
- vmtool 利用JVMTI接口,实现查询内存对象,强制GC等,包含很多强大的功能。
1)获取MathGame实例
[arthas@17]$ vmtool --action getInstances --className demo.MathGame
@MathGame[][
@MathGame[demo.MathGame@32733fdd],
]
2)强制GC
vmtool --action forceGc
- perfcounter查看当前JVM的 Perf Counter信息
$ perfcounter
java.ci.totalTime 2325637411
java.cls.loadedClasses 3403
java.cls.sharedLoadedClasses 0
java.cls.sharedUnloadedClasses 0
java.cls.unloadedClasses 0
java.property.java.version 11.0.4
java.property.java.vm.info mixed mode
java.property.java.vm.name OpenJDK 64-Bit Server VM
- logger 查看logger信息,更新logger level
1)查看logger信息
[arthas@2062]$ logger
name ROOT
class ch.qos.logback.classic.Logger
classLoader sun.misc.Launcher$AppClassLoader@2a139a55
classLoaderHash 2a139a55
level INFO
effectiveLevel INFO
additivity true
codeSource file:/Users/hengyunabc/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar
appenders name CONSOLE
class ch.qos.logback.core.ConsoleAppender
classLoader sun.misc.Launcher$AppClassLoader@2a139a55
classLoaderHash 2a139a55
target System.out
name APPLICATION
class ch.qos.logback.core.rolling.RollingFileAppender
classLoader sun.misc.Launcher$AppClassLoader@2a139a55
classLoaderHash 2a139a55
file app.log
name ASYNC
class ch.qos.logback.classic.AsyncAppender
classLoader sun.misc.Launcher$AppClassLoader@2a139a55
classLoaderHash 2a139a55
appenderRef [APPLICATION]
2)查看指定classloader的logger信息
[arthas@2062]$ logger -c 2a139a55
name ROOT
class ch.qos.logback.classic.Logger
classLoader sun.misc.Launcher$AppClassLoader@2a139a55
classLoaderHash 2a139a55
level DEBUG
effectiveLevel DEBUG
additivity true
codeSource file:/Users/hengyunabc/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar
appenders name CONSOLE
class ch.qos.logback.core.ConsoleAppender
classLoader sun.misc.Launcher$AppClassLoader@2a139a55
classLoaderHash 2a139a55
target System.out
name APPLICATION
class ch.qos.logback.core.rolling.RollingFileAppender
classLoader sun.misc.Launcher$AppClassLoader@2a139a55
classLoaderHash 2a139a55
file app.log
name ASYNC
class ch.qos.logback.classic.AsyncAppender
classLoader sun.misc.Launcher$AppClassLoader@2a139a55
classLoaderHash 2a139a55
appenderRef [APPLICATION]
3)更新logger level
[arthas@2062]$ logger --name ROOT --level debug
update logger level success.
- ognl执行ognl表达式
- express 执行的表达式
- [c:] 执行表达式的 ClassLoader 的 hashcode,默认值是SystemClassLoader
- [classLoaderClass:] 指定执行表达式的 ClassLoader 的 class name
- 结果对象的展开层次,默认值1
OGNL特殊用法请参考:https://github.com/alibaba/arthas/issues/71 OGNL表达式官方指南:https://commons.apache.org/proper/commons-ognl/language-guide.html
1)获取静态类的静态字段
$ ognl '@demo.MathGame@random'
@Random[
serialVersionUID=@Long[3905348978240129619],
seed=@AtomicLong[125451474443703],
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[-3282039941672302964],
nextNextGaussian=@Double[0.0],
haveNextNextGaussian=@Boolean[false],
serialPersistentFields=@ObjectStreamField[][isEmpty=false;size=3],
unsafe=@Unsafe[sun.misc.Unsafe@28ea5898],
seedOffset=@Long[24],
]
2)执行多行表达式,赋值给临时变量,返回一个List
$ ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
@ArrayList[
@String[/opt/java/8.0.181-zulu/jre],
@String[OpenJDK Runtime Environment],
]
- mbean查看 Mbean 的信息
- name-pattern 名称表达式匹配
- attribute-pattern 属性名表达式匹配
- [m] 查看元信息
- [i:] 刷新属性值的时间间隔 (ms)
- [n:] 刷新属性值的次数
- [E] 开启正则表达式匹配,默认为通配符匹配。仅对属性名有效
1)列出所有 Mbean 的名称:
mbean
2)查看 Mbean 的元信息:
mbean -m java.lang:type=Threading
3)查看mbean属性信息:
mbean java.lang:type=Threading
4)mbean的name支持通配符匹配:
mbean java.lang:type=Th*
- heapdump dump java heap, 类似jmap命令的heap dump功能
- heapdump [-h] [-l] [file]
1)dump到指定文件
[arthas@58205]$ heapdump /tmp/dump.hprof
Dumping heap to /tmp/dump.hprof...
Heap dump file created
2)只dump live对象
[arthas@58205]$ heapdump --live /tmp/dump.hprof
Dumping heap to /tmp/dump.hprof...
Heap dump file created
3、类命令
- sc ,查看JVM已加载的类信息
- class-pattern 类名表达式匹配
- method-pattern 方法名表达式匹配
- [d] 输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。
- 如果一个类被多个ClassLoader所加载,则会出现多次
- [E] 开启正则表达式匹配,默认为通配符匹配
- [f] 输出当前类的成员变量信息(需要配合参数-d一起使用)
- [x:] 指定输出静态变量时属性的遍历深度,默认为 0,即直接使用 toString 输出
- [c:] 指定class的 ClassLoader 的 hashcode
- [classLoaderClass:] 指定执行表达式的 ClassLoader 的 class name
- [n:] 具有详细信息的匹配类的最大数量(默认为100)
模糊搜索
$ sc demo.*
demo.MathGame
Affect(row-cnt:1) cost in 55 ms.
打印类的详细信息
$ sc -d demo.MathGame
class-info demo.MathGame
code-source /private/tmp/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@3d4eac69
+-sun.misc.Launcher$ExtClassLoader@66350f69
classLoaderHash 3d4eac69
Affect(row-cnt:1) cost in 875 ms.
打印出类的Field信息
$ sc -d -f demo.MathGame
class-info demo.MathGame
code-source /private/tmp/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@3d4eac69
+-sun.misc.Launcher$ExtClassLoader@66350f69
classLoaderHash 3d4eac69
fields modifierprivate,static
type java.util.Random
name random
value java.util.Random@522b4
08a
modifierprivate
type int
name illegalArgumentCount
Affect(row-cnt:1) cost in 19 ms.
- sm ,查看已加载类的方法信息
- class-pattern 类名表达式匹配
- method-pattern 方法名表达式匹配
- [d] 展示每个方法的详细信息
- [E] 开启正则表达式匹配,默认为通配符匹配
- [c:] 指定class的 ClassLoader 的 hashcode
- [classLoaderClass:] 指定执行表达式的 ClassLoader 的 class name
- [n:] 具有详细信息的匹配类的最大数量(默认为100)
查看类中都有哪些方法
[arthas@42]$ sm java.lang.String
java.lang.String-><init>
java.lang.String->equals
java.lang.String->toString
java.lang.String->hashCode
Affect(row-cnt:44) cost in 1342 ms.
查看类中方法的声明等信息
[arthas@42]$ sm -d java.lang.String isBlank
declaring-class java.lang.String
method-name isBlank
modifier public
annotation
parameters
return boolean
exceptions
classLoaderHash null
Affect(row-cnt:1) cost in 9 ms.
- jad ,反编译指定已加载类的源码
- class-pattern 类名表达式匹配
- [c:] 类所属 ClassLoader 的 hashcode
- [classLoaderClass:] 指定执行表达式的 ClassLoader 的 class name
- [E] 开启正则表达式匹配,默认为通配符匹配
1)反编译某个类的内容
[arthas@42]$ jad demo.MathGame
ClassLoader:
+-jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44
+-jdk.internal.loader.ClassLoaders$PlatformClassLoader@cb7268e
Location:
/root/math-game.jar
/*
* Decompiled with CFR.
*/
package demo;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class MathGame {
private static Random random = new Random();
private int illegalArgumentCount = 0;
2)反编译看某个方法内容
[arthas@42]$ jad demo.MathGame main
ClassLoader:
+-jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44
+-jdk.internal.loader.ClassLoaders$PlatformClassLoader@cb7268e
Location:
/root/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);
}
}
Affect(row-cnt:1) cost in 117 ms.
- mc-retransform ,加载外部的.class文件,retransform jvm已加载的类。
传送门:retransform命令
retransform 指定的 .class 文件
$ retransform /tmp/MathGame.class
retransform success, size: 1, classes:
demo.MathGame
- ms-redefine , 加载外部的.class文件,redefine jvm已加载的类。
- [c:] ClassLoader的hashcode
- [classLoaderClass:] 指定执行表达式的 ClassLoader 的 class name
redefine的限制
不允许新增加field/method
正在跑的函数,没有退出不能生效,比如下面新增加的System.out.println,只有run()函数里的会生效
- dump ,dump 已加载类的 bytecode 到特定目录
- class-pattern 类名表达式匹配
- [c:] 类所属 ClassLoader 的 hashcode
- [classLoaderClass:] 指定执行表达式的 ClassLoader 的 class name
- [d:] 设置类文件的目标目录
- [E] 开启正则表达式匹配,默认为通配符匹配
1)将指定类到某个目录中
$ dump java.lang.String
HASHCODE CLASSLOADER LOCATION
null /Users/admin/logs/arthas/classdump/java/lang/String.class
Affect(row-cnt:1) cost in 119 ms.
$ dump demo.*0
HASHCODE CLASSLOADER LOCATION
3d4eac69 +-sun.misc.Launcher$AppClassLoader@3d4eac69 /Users/admin/logs/arthas/classdump/sun.misc.Launcher$AppClassLoader-3d4eac69/demo/MathGame.class
+-sun.misc.Launcher$ExtClassLoader@66350f69
Affect(row-cnt:1) cost in 39 ms.
- classloader ,查看classloader的继承树,urls,类加载信息
- [l] 按类加载实例进行统计
- [t] 打印所有ClassLoader的继承树
- [a] 列出所有ClassLoader加载的类,请谨慎使用
- [c:] ClassLoader的hashcode
- [classLoaderClass:] 指定执行表达式的 ClassLoader 的 class name
- [c: r:] 用ClassLoader去查找resource
- [c: load:] 用ClassLoader去加载指定的类
1)查看ClassLoader的继承树
[arthas@64]$ classloader -t
+-BootstrapClassLoader
+-jdk.internal.loader.ClassLoaders$PlatformClassLoader@74fe65fd
+-com.taobao.arthas.agent.ArthasClassloader@328f8ec3
+-jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44
Affect(row-cnt:4) cost in 7 ms.
2)使用ClassLoader去加载类
$ classloader -c 3d4eac69 --load demo.MathGame
load class success.
class-info demo.MathGame
code-source /private/tmp/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@3d4eac69
+-sun.misc.Launcher$ExtClassLoader@66350f69
classLoaderHash 3d4eac69
4、增强命令
- monitor ,方法执行监控
- class-pattern 类名表达式匹配
- method-pattern 方法名表达式匹配
- condition-express 条件表达式
- [E] 开启正则表达式匹配,默认为通配符匹配
- [c:] 统计周期,默认值为120秒
- [b] 在方法调用之前计算condition-express
1)监控某个方法
[arthas@64]$ monitor -c 5 demo.MathGame primeFactors
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 96 ms, listenerId: 1
timestamp class method total success fail avg-rt(ms) fail-rate
------------------------------------------------------------------------------------------------------------
2022-02-13 11:41:47 demo.MathGame primeFactors 5 3 2 1.37 40.00%
字段说明
timestamp 时间戳
class Java类
method 方法(构造方法、普通方法)
total 调用次数
success 成功次数
fail 失败次数
rt 平均RT
fail-rate 失败率
2)计算条件表达式过滤统计结果(方法执行完毕之后)
monitor -c 5 demo.MathGame primeFactors "params[0] <= 2"
3)计算条件表达式过滤统计结果(方法执行完毕之前)
monitor -b -c 5 com.test.testes.MathGame primeFactors "params[0] <= 2"
- watch ,函数执行数据观测,范围为:返回值、抛出异常、入参,通过编写OGNL 表达式进行对应变量的查看
- class-pattern 类名表达式匹配
- method-pattern 函数名表达式匹配
- express 观察表达式,默认值:{params, target, returnObj}
- condition-express 条件表达式
- [b] 在函数调用之前观察
- [e] 在函数异常之后观察
- [s] 在函数返回之后观察
- [f] 在函数结束之后(正常返回和异常返回)观察
- [E] 开启正则表达式匹配,默认为通配符匹配
- [x:] 指定输出结果的属性遍历深度,默认为 1
传送门:watch命令
特别说明:
watch 命令定义了4个观察事件点,即 -b 函数调用前,-e 函数异常后,-s 函数返回后,-f 函数结束后
4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
这里要注意函数入参和函数出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表函数入参外,其余事件都代表函数出参
当使用 -b 时,由于观察事件点是在函数调用前,此时返回值或异常均不存在
在watch命令的结果里,会打印出location信息。location有三种可能值:AtEnter,AtExit,AtExceptionExit。对应函数入口,函数正常return,函数抛出异常。
1)观察函数调用返回时的参数、this对象和返回值
[arthas@64]$ watch demo.MathGame primeFactors -x 2
Affect(class count: 1 , method count: 1) cost in 32 ms, listenerId: 5
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2021-08-31 15:22:57; [cost=0.220625ms] result=@ArrayList[
@Object[][
@Integer[-179173],
],
@MathGame[
random=@Random[java.util.Random@31cefde0],
illegalArgumentCount=@Integer[44],
],
null,
]
method=demo.MathGame.primeFactors location=AtExit
ts=2021-08-31 15:22:58; [cost=1.020982ms] result=@ArrayList[
@Object[][
@Integer[1],
],
@MathGame[
random=@Random[java.util.Random@31cefde0],
illegalArgumentCount=@Integer[44],
],
@ArrayList[
@Integer[2],
@Integer[2],
@Integer[26947],
],
]
上面的结果里,说明函数被执行了两次,第一次结果是location=AtExceptionExit,说明函数抛出异常了,因此returnObj是null
在第二次结果里是location=AtExit,说明函数正常返回,因此可以看到returnObj结果是一个ArrayList
2)观察函数调用入口的参数和返回值
$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 50 ms.
ts=2018-12-03 19:23:23; [cost=0.0353ms] result=@ArrayList[
@Object[][
@Integer[-1077465243],
],
null,
]
3)同时观察函数调用前和函数返回后
[arthas@64]$ watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 46 ms.
ts=2018-12-03 19:29:54; [cost=0.01696ms] result=@ArrayList[
@Object[][
@Integer[1],
],
@MathGame[
random=@Random[java.util.Random@522b408a],
illegalArgumentCount=@Integer[13038],
],
null,
]
ts=2018-12-03 19:29:54; [cost=4.277392ms] result=@ArrayList[
@Object[][
@Integer[1],
],
@MathGame[
random=@Random[java.util.Random@522b408a],
illegalArgumentCount=@Integer[13038],
],
@ArrayList[
@Integer[2],
@Integer[2],
@Integer[2],
@Integer[5],
@Integer[5],
@Integer[73],
@Integer[241],
@Integer[439],
],
]
- trace ,方法内部调用路径,并输出方法路径上的每个节点上耗时
- class-pattern 类名表达式匹配
- method-pattern 方法名表达式匹配
- condition-express 条件表达式
- [E] 开启正则表达式匹配,默认为通配符匹配
- [n:] 命令执行次数
#cost
方法执行耗时
1)trace函数
[arthas@64]$ trace demo.MathGame run
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 62 ms, listenerId: 5
`---ts=2022-02-13 12:03:37;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44
`---[0.458383ms] demo.MathGame:run()
`---[0.107551ms] demo.MathGame:primeFactors() #24 [throws Exception]
`---ts=2022-02-13 12:03:38;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44
`---[0.711154ms] demo.MathGame:run()
+---[0.457633ms] demo.MathGame:primeFactors() #24
`---[0.142881ms] demo.MathGame:print() #25
2)据调用耗时过滤
$ trace demo.MathGame run '#cost > 10'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 41 ms.
`---ts=2018-12-04 01:12:02;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
`---[12.033735ms] demo.MathGame:run()
+---[0.006783ms] java.util.Random:nextInt()
+---[11.852594ms] demo.MathGame:primeFactors()
`---[0.05447ms] demo.MathGame:print()
- stack ,输出当前方法被调用的调用路径
- class-pattern 类名表达式匹配
- method-pattern 方法名表达式匹配
- condition-express 条件表达式
- [E] 开启正则表达式匹配,默认为通配符匹配
- [n:] 执行次数限制
传送门:stack命令
1)stack命令
$ stack demo.MathGame primeFactors
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 36 ms.
ts=2018-12-04 01:32:19;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
@demo.MathGame.run()
at demo.MathGame.main(MathGame.java:16)
2)据执行时间来过滤
$ stack demo.MathGame primeFactors '#cost>5'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 35 ms.
ts=2018-12-04 01:35:58;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
@demo.MathGame.run()
at demo.MathGame.main(MathGame.java:16)
- tt ,方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
传送门:tt命令
- profiler ,使用async-profiler生成火焰图
- action 要执行的操作
- actionArg 属性名模式
- [i:] 采样间隔(单位:ns)(默认值:10’000’000,即10 ms)
- [f:] 将输出转储到指定路径
- [d:] 运行评测指定秒
- [e:] 要跟踪哪个事件(cpu, alloc, lock, cache-misses等),默认是cpu
传送门:profiler命令
启动profiler
$ profiler start
Started [cpu] profiling
默认情况下,生成的是cpu的火焰图,即event为cpu。可以用--event参数来指定。
获取已采集的sample的数量
$ profiler getSamples
23
查看profiler状态
$ profiler status
[cpu] profiling is running for 4 seconds
可以查看当前profiler在采样哪种event和采样时间。
停止profiler
生成html格式结果
默认情况下,结果文件是html格式,也可以用--format参数指定:
$ profiler stop --format html
profiler output file: /tmp/test/arthas-output/20211207-111550.html
OK
或者在--file参数里用文件名指名格式。比如--file /tmp/result.html 。
通过浏览器查看arthas-output下面的profiler结果