本博文来源于学习阿里云知行动手实验室笔记,传送门
写在前面,博主从17年接触到Java,开启半年自学入行,博客名为逆流者blog,希望一直可以保持乐观、积极的学习心态,在编程的世界里逆流而上。
Java 诊断工具 Arthas 基础教程
Arthas 基础教程
Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。
Arthas 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。
Github: https://github.com/alibaba/arthas
文档: https://arthas.aliyun.com/doc/
启动arthas-demo
下载arthas-demo.jar,再用java -jar命令启动:
wget https://arthas.aliyun.com/arthas-demo.jar;java -jar arthas-demo.jar
arthas-demo是一个很简单的程序,它随机生成整数,再执行因式分解,把结果打印出来。如果生成的随机数是负数,则会打印提示信息。
比如一些打印提示信息:
--2022-07-28 11:39:12-- https://arthas.aliyun.com/arthas-demo.jar
Resolving arthas.aliyun.com (arthas.aliyun.com)... 203.119.207.129
Connecting to arthas.aliyun.com (arthas.aliyun.com)|203.119.207.129|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 4499 (4.4K) [application/java-archive]
Saving to: ‘arthas-demo.jar’
arthas-demo.jar 100%[==========>] 4.39K --.-KB/s in 0s
2022-07-28 11:39:12 (44.0 MB/s) - ‘arthas-demo.jar’ saved [4499/4499]
111330=2*3*3*5*1237
151728=2*2*2*2*3*29*109
illegalArgumentCount: 1, number is: -46721, need >= 2
19857=3*6619
93218=2*127*367
165986=2*149*557
illegalArgumentCount: 2, number is: -164359, need >= 2
illegalArgumentCount: 3, number is: -210982, need >= 2
211310=2*5*11*17*113
54104=2*2*2*6763
启动arthas-boot
在新的Terminal 2里,下载arthas-boot.jar,再用java -jar命令启动:
wget https://arthas.aliyun.com/arthas-boot.jar;java -jar arthas-boot.jar
arthas-boot是Arthas的启动程序,它启动后,会列出所有的Java进程,用户可以选择需要诊断的目标进程。
Requesting a Cloud Shell.Succeeded.
Connecting terminal
Welcome to Alibaba Cloud Shell!
Type "help" to learn about Cloud Shell
Type "aliyun" to use Alibaba Cloud CLI
shell@Alicloud:~$ wget https://arthas.aliyun.com/arthas-boot.jar;java -jar arthas-boot.jar
--2022-07-28 11:49:44-- https://arthas.aliyun.com/arthas-boot.jar
Resolving arthas.aliyun.com (arthas.aliyun.com)... 203.119.207.243
Connecting to arthas.aliyun.com (arthas.aliyun.com)|203.119.207.243|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 141872 (139K) [application/java-archive]
Saving to: ‘arthas-boot.jar’
arthas-boot.jar 100%[====================================================>] 138.55K 343KB/s in 0.4s
2022-07-28 11:49:46 (343 KB/s) - ‘arthas-boot.jar’ saved [141872/141872]
[INFO] arthas-boot version: 3.6.3
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 1265 arthas-demo.jar
选择第一个进程,输入 1 ,再Enter/回车:
1
Attach成功之后,会打印Arthas LOGO。
[INFO] Start download arthas from remote server: https://arthas.aliyun.com/download/3.6.2?mirror=aliyun
[INFO] Download arthas success.
[INFO] arthas home: /home/shell/.arthas/lib/3.6.2/arthas
[INFO] Try to attach process 1265
[INFO] Attach process 1265 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 3.6.2
main_class
pid 1265
time 2022-07-28 11:50:39
[arthas@1265]$
输入 help 可以获取到更多的帮助信息。
help
显示了可以在[arthas@1265]$
中的命令
NAME DESCRIPTION
help Display Arthas Help
auth Authenticates the current session
keymap Display all the available keymap for the specified connection.
sc Search all the classes loaded by JVM
sm Search the method of classes loaded by JVM
classloader Show classloader info
jad Decompile class
getstatic Show the static field of a class
monitor Monitor method execution statistics, e.g. total/success/failure count, average rt, fail rate, etc.
stack Display the stack trace for the specified class and method
thread Display thread info, thread stack
trace Trace the execution time of specified method invocation.
watch Display the input/output parameter, return object, and thrown exception of specified method invocation
tt Time Tunnel
jvm Display the target JVM information
memory Display jvm memory info.
perfcounter Display the perf counter information.
ognl Execute ognl expression.
mc Memory compiler, compiles java files into bytecode and class files in memory.
redefine Redefine classes. @see Instrumentation#redefineClasses(ClassDefinition...)
retransform Retransform classes. @see Instrumentation#retransformClasses(Class...)
dashboard Overview of target jvm's thread, memory, gc, vm, tomcat info.
dump Dump class byte array from JVM
heapdump Heap dump
options View and change various Arthas options
cls Clear the screen
reset Reset all the enhanced classes
version Display Arthas version
session Display current session information
sysprop Display, and change the system properties.
sysenv Display the system env.
vmoption Display, and update the vm diagnostic options.
logger Print logger info, and update the logger level
history Display command history
cat Concatenate and print files
base64 Encode and decode using Base64 representation
echo write arguments to the standard output
pwd Return working directory name
mbean Display the mbean information
grep grep command for pipes.
tee tee command for pipes.
profiler Async Profiler. https://github.com/jvm-profiling-tools/async-profiler
vmtool jvm tool
stop Stop/Shutdown Arthas server and exit the console.
Dashboard
dashboard 命令可以查看当前系统的实时数据面板。
dashboard
ID NAME GROUP PRIORITY STATE %CPU DELTA_TIME TIME INTERRUPTE DAEMON
-1 C1 CompilerThread1 - -1 - 0.17 0.008 0:0.453 false true
22 Timer-for-arthas-dashboard-259 system 5 RUNNABLE 0.17 0.008 0:0.040 false true
20 arthas-NettyHttpTelnetBootstra system 5 RUNNABLE 0.09 0.004 0:0.097 false true
-1 VM Periodic Task Thread - -1 - 0.08 0.003 0:0.390 false true
1 main main 5 TIMED_WAI 0.02 0.001 0:0.189 false false
-1 C2 CompilerThread0 - -1 - 0.02 0.000 0:0.551 false true
-1 VM Thread - -1 - 0.01 0.000 0:0.105 false true
16 arthas-shell-server system 9 TIMED_WAI 0.0 0.000 0:0.002 false true
17 arthas-session-manager system 9 TIMED_WAI 0.0 0.000 0:0.000 false true
2 Reference Handler system 10 WAITING 0.0 0.000 0:0.001 false true
3 Finalizer system 8 WAITING 0.0 0.000 0:0.002 false true
4 Signal Dispatcher system 9 RUNNABLE 0.0 0.000 0:0.000 false true
8 Attach Listener system 9 RUNNABLE 0.0 0.000 0:0.025 false true
10 arthas-timer system 9 WAITING 0.0 0.000 0:0.000 false true
13 arthas-NettyHttpTelnetBootstra system 5 RUNNABLE 0.0 0.000 0:0.025 false true
14 arthas-NettyWebsocketTtyBootst system 5 RUNNABLE 0.0 0.000 0:0.001 false true
15 arthas-NettyWebsocketTtyBootst system 5 RUNNABLE 0.0 0.000 0:0.001 false true
18 arthas-UserStat system 9 WAITING 0.0 0.000 0:0.000 false true
21 arthas-command-execute system 5 TIMED_WAI 0.0 0.000 0:0.017 false true
-1 Service Thread - -1 - 0.0 0.000 0:0.000 false true
Memory used total max usage GC
heap 19M 42M 444M 4.32% gc.copy.count 8
eden_space 1M 11M 122M 1.35% gc.copy.time(ms) 48
survivor_space 0K 1472K 15680K 0.00% gc.marksweepcompact.count 1
tenured_gen 17M 29M 306M 5.72% gc.marksweepcompact.time(ms) 27
nonheap 27M 28M -1 96.78%
code_cache 4M 4M 240M 1.97%
metaspace 20M 21M -1 96.58%
compressed_class_space 2M 2M 1024M 0.25%
direct 8K 8K - 100.01%
mapped 0K 0K - 0.00%
Runtime
os.name Linux
os.version 3.10.0-957.21.3.el7.x86_64
java.version 1.8.0_292
java.home /usr/lib/jvm/java-8-openjdk-amd64/jre
systemload.average 0.00
processors 1
timestamp/uptime Thu Jul 28 11:57:43 CST 2022/483s
输入 q 或者 Ctrl+C 可以退出dashboard命令。
Thread
thread 1 命令会打印线程ID 1的栈。
thread 1
"main" Id=1 TIMED_WAITING
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at demo.MathGame.main(MathGame.java:17)
Arthas支持管道,可以用 thread 1 | grep ‘main(’ 查找到main class。
thread 1 | grep 'main('
可以直接找到main(这一行
at demo.MathGame.main(MathGame.java:17)
这样可以看到main class是demo.MathGame 17这一行
Sc
可以通过 sc 命令来查找JVM里已加载的类:
sc -d *MathGame
查到 demo.MathGame 类的信息
class-info demo.MathGame
code-source /home/shell/arthas-demo.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@1b6d3586
+-sun.misc.Launcher$ExtClassLoader@4680ef6b
classLoaderHash 1b6d3586
Affect(row-cnt:1) cost in 44 ms.
Jad
可以通过 jad 命令来反编译代码:
jad demo.MathGame
ClassLoader:
+-sun.misc.Launcher$AppClassLoader@1b6d3586
+-sun.misc.Launcher$ExtClassLoader@4680ef6b
Location:
/home/shell/arthas-demo.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();
public int illegalArgumentCount = 0;
public List<Integer> primeFactors(int number) {
/*44*/ if (number < 2) {
/*45*/ ++this.illegalArgumentCount;
throw new IllegalArgumentException("number is: " + number + ", need >= 2");
}
ArrayList<Integer> result = new ArrayList<Integer>();
/*50*/ int i = 2;
/*51*/ while (i <= number) {
/*52*/ if (number % i == 0) {
/*53*/ result.add(i);
/*54*/ number /= i;
/*55*/ i = 2;
continue;
}
/*57*/ ++i;
}
/*61*/ return result;
}
public static void main(String[] args) throws InterruptedException {
MathGame game = new MathGame();
while (true) {
/*16*/ game.run();
/*17*/ TimeUnit.SECONDS.sleep(1L);
}
}
public void run() throws InterruptedException {
try {
/*23*/ int number = random.nextInt() / 10000;
/*24*/ List<Integer> primeFactors = this.primeFactors(number);
/*25*/ MathGame.print(number, primeFactors);
}
catch (Exception e) {
/*28*/ System.out.println(String.format("illegalArgumentCount:%3d, ", this.illegalArgumentCount) + e.getMessage());
}
}
public static void print(int number, List<Integer> primeFactors) {
StringBuffer sb = new StringBuffer(number + "=");
/*34*/ for (int factor : primeFactors) {
/*35*/ sb.append(factor).append('*');
}
/*37*/ if (sb.charAt(sb.length() - 1) == '*') {
/*38*/ sb.deleteCharAt(sb.length() - 1);
}
/*40*/ System.out.println(sb);
}
}
Affect(row-cnt:1) cost in 1233 ms.
Watch
通过watch命令可以查看函数的参数/返回值/异常信息。
查看demo.MathGame类 primeFactors方法的返回值:
watch demo.MathGame primeFactors returnObj
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 245 ms, listenerId: 1
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2022-07-28 14:34:00; [cost=0.899344ms] result=null
method=demo.MathGame.primeFactors location=AtExit
ts=2022-07-28 14:34:01; [cost=0.913815ms] result=@ArrayList[
@Integer[2],
@Integer[52433],
]
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2022-07-28 14:34:02; [cost=0.065352ms] result=null
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2022-07-28 14:34:03; [cost=0.040286ms] result=null
method=demo.MathGame.primeFactors location=AtExit
ts=2022-07-28 14:34:04; [cost=0.435046ms] result=@ArrayList[
@Integer[2],
@Integer[25439],
]
输入 q 或者 Ctrl+C 退出watch命令。
Exit/Stop
退出Arthas
用 exit 或者 quit 命令可以退出Arthas。
exit
退出Arthas之后,还可以再次用 java -jar arthas-boot.jar 来连接。
java -jar arthas-boot.jar
彻底退出Arthas
exit/quit命令只是退出当前session,arthas server还在目标进程中运行。
想完全退出Arthas,可以执行 stop 命令。
stop