Hey, are you struggling with debugging and diagnosing issues in Java development?
Don't worry, I'm going to tell you a secret weapon! It's like a superhero who can unleash your potential and solve your troubles! Its name is Arthas, it is a Java diagnostic tool, it is the savior of developers!
It can not only help you monitor and analyze the running status of Java applications in real time, but also allow you to perform online debugging in the production environment. It is like a god! Whether viewing method call stacks, monitoring thread status, or dynamically modifying code, Arthas can handle it with ease!
1 Introduction
Alibaba Arthas is a diagnostic tool that can be used to monitor, analyze and solve problems of Java applications. A major advantage of using Arthas is that we don't need to modify the code or even restart the Java services we want to monitor.
In this tutorial, we will first install Arthas, and after that, demonstrate some key features of Arthas through a simple case.
Finally, since Arthas is written in Java, it is cross-platform and runs on Linux, macOS, and Windows.
2. Download and Getting Started
First, we can download the Arthas library via a direct download link or using curl:
curl -O https://alibaba.github.io/arthas/arthas-boot.jar
Now, let's test that it works by running Arthas with the -h (help) option:
java -jar arthas-boot.jar -h
If successful, we should see the help guide showing all commands:
3. Case study
In this tutorial we'll use a very simple application, based on a relatively inefficient implementation of the Fibonacci sequence implemented using recursion:
public class FibonacciGenerator {
public static void main(String[] args) {
System.out.println("按任意键继续");
System.in.read();
for (int i = 0; i < 100; i++) {
long result = fibonacci(i);
System.out.println(format("fib(%d): %d", i, result));
}
}
public static long fibonacci(int n) {
if (n == 0 || n == 1) {
return 1L;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
}
The most interesting part of this example is the fibonacci method that follows the mathematical definition of the Fibonacci sequence.
In the main method, we use a loop and relatively large numbers in order to let the computer do the calculations for a long time. This is of course exactly what we want in order to demonstrate Arthas.
4. Start Arthas
Let's try Arthas now! The first thing we need to do is run our little Fibonacci application. We can use our favorite IDE or run it directly in the terminal. It will ask to press a key to start. We will press any key after attaching the process to Arthas.
Now, let's run the Arthas executable:
java -jar arthas-boot.jar
Arthas prompts for a process to attach to:
[INFO] arthas-boot version: 3.1.7
[INFO] Found existing java process, please choose one and hit RETURN.
* [1]: 25500 com.baeldung.arthas.FibonacciGenerator
...
Let's select the process named com.baeldung.arthas.FibonacciGenerator. In this example, simply enter the number '1' into the list and press Enter.
Arthas will now attach to the process and start:
[INFO] Try to attach process 25500
[INFO] Attach process 25500 success.
...
Once Arthas starts, we have a prompt where we can issue different commands.
We can use the help command to get more information about available options. In order to facilitate the use of Arthas, we can also use the tab key to automatically complete its commands.
With Arthas attached to the process, we can now press a key and the program will start printing Fibonacci numbers.
5. Dashboard
Once Arthas is started, we can use the dashboard. In this case, we use the dashboard by typing the "dashboard" command. We can now see a detailed screen with several panels and lots of information about our Java process:
Let's look at some of these in more detail:
-
The top area is dedicated to displaying currently running threads
-
An important column is the CPU usage per thread
-
The third part shows the CPU time of each thread
-
Another interesting panel is memory analysis. The different memory regions are listed along with their statistics. On the right we have information for the garbage collector
-
Finally, in the fifth section, we have information about the host platform and the JVM
We can exit the dashboard by pressing the "q" key.
We should remember that even after exiting, Arthas will still be attached to our process. Therefore, in order to properly disconnect it from our process, we need to run the "stop" command.
6. Analyzing stack traces
In the dashboard, we see that our main process is using almost 100% of the CPU. The process ID is 1, as you can see in the first column.
Now that we've exited the dashboard, we can analyze the process in more detail by running the "thread" command :
thread 1
The number passed as an argument is the thread ID. Arthas prints a stack trace filled with calls to fibonacci methods.
If the stack trace is long and hard to read, you can use the "thread" command combined with the "grep" command to filter it:
thread 1 | grep 'main('
This will only print lines that match the "grep" command:
[arthas@25500]$ thread 1 | grep 'main('
at com.baeldung.arthas.FibonacciGenerator.main(FibonacciGenerator.java:10)
7. Decompile Java classes
Suppose we are analyzing a Java application about which we know little or nothing, and suddenly find that the stack is filled with repeated calls of the following types:
[arthas@59816]$ thread 1
"main" Id=1 RUNNABLE
at app//com.baeldung.arthas.FibonacciGenerator.fibonacci(FibonacciGenerator.java:18)
at app//com.baeldung.arthas.FibonacciGenerator.fibonacci(FibonacciGenerator.java:18)
...
Since we ran Arthas, we can decompile a class to see its contents. To achieve this, we can use the jad command, passing the qualified class name as an argument:
jad com.baeldung.arthas.FibonacciGenerator
类加载器:
+-jdk.internal.loader.ClassLoaders $ AppClassLoader @ 799f7e29
+-jdk.internal.loader.ClassLoaders $ PlatformClassLoader @ 60f1dd34
位置:
/home/amoreno/work/baeldung/tutorials/libraries-3/target/
/*
* 反编译使用CFR。
*/
package com.baeldung.arthas;
import java.io.IOException;
import java.io.InputStream;
importjava.io.PrintStream;
public class FibonacciGenerator {
public static void main(String[] arrstring) throws IOException {
The output is the decompiled Java class and some useful metadata like the location of the class. This is a very useful and powerful feature.
8. Search class and search method
The Search Classes command is very handy when searching for classes loaded in the JVM. We can use this by typing sc and passing the pattern as an argument, with or without wildcards:
[arthas@70099]$ sc *Fibonacci*
com.baeldung.arthas.FibonacciGenerator
Affect(row-cnt:1) cost in 5 ms.
Once we have the qualified name of a class, we can use two additional flags to find more information:
-
-d show class details
-
-f show the fields of the class
However, the fields of the class must be queried with the details:
[arthas@70099]$ sc -df com.baeldung.arthas.FibonacciGenerator
class-info com.baeldung.arthas.FibonacciGenerator
...
Similarly, we can use the sm (search method) command to find methods loaded in a class. In this case, for our class com.baeldung.arthas.FibonacciGenerator, we can run:
[arthas@70099]$ sm com.baeldung.arthas.FibonacciGenerator
com.baeldung.arthas.FibonacciGenerator <init>()V
com.baeldung.arthas.FibonacciGenerator main([Ljava/lang/String;)V
com.baeldung.arthas.FibonacciGenerator fibonacci(I)J
Affect(row-cnt:3) cost in 4 ms.
We can use the -d flag to retrieve method details. Finally, we can pass the name of the method as an optional parameter to narrow down the number of returned methods:
sm -d com.baeldung.arthas.FibonacciGenerator fibonacci
declaring-class com.baeldung.arthas.FibonacciGenerator
method-name fibonacci
modifier public,static
annotation
parameters int
return long
exceptions
classLoaderHash 799f7e29
9. Monitoring method calls
We can use Arthas to monitor methods, which is very handy when debugging performance issues of the application. For this, we can use the monitor command.
The monitor command takes a -c <seconds> flag and two arguments - qualified class name and method name.
For our case study, let's call monitor:
monitor -c 10 com.baeldung.arthas.FibonacciGenerator fibonacci
As we expected, Arthas will print metrics about the fibonacci method every 10 seconds:
Affect(class-cnt:1 , method-cnt:1) cost in 47 ms.
timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------------------------------------
2020-03-07 11:43:26 com.baeldung.arthas.FibonacciGenerator fibonacci 528957 528957 0 0.07 0.00%
...
We also have metrics for those calls that eventually fail - this is useful for debugging.
10. Monitoring Method Parameters
If we need to debug the parameters of the method, we can use the watch command. However, the syntax is slightly more complicated:
watch com.baeldung.arthas.FibonacciGenerator fibonacci '{params[0], returnObj}' 'params[0]>10' -n 10
Let's look at each parameter in detail:
-
The first parameter is the class name
-
The second parameter is the method name
-
The third parameter is an OGNL expression that defines what we want to look at - in this case it's the first (and only) method parameter and return value
-
The fourth and last optional parameter is a boolean expression to filter the calls we want to monitor
For this example, we only want to watch when the parameter is greater than 10. Finally, we add a flag to limit the results to 10:
watch com.baeldung.arthas.FibonacciGenerator fibonacci '{params[0], returnObj}' 'params[0]>10' -n 10
按Q或Ctrl+C中断。
Affect(class-cnt:1 , method-cnt:1) cost in 19 ms.
ts=2020-02-17 21:48:08; [cost=30.165211ms] result=@ArrayList[
@Integer[11],
@Long[144],
]
ts=2020-02-17 21:48:08; [cost=50.405506ms] result=@ArrayList[
@Integer[12],
@Long[233],
]
...
Here we can see an example of a call with CPU time and input/return values.
11. Analyzer
For those interested in application performance, a very intuitive capability is provided through the profiler command. The profiler will evaluate the performance of the CPU our process is using.
Let's start the profiler by running profiler start. This is a non-blocking task, meaning we can keep using Arthas while the profiler is working.
At any time you can ask the profiler how many samples it has by running profiler getSamples .
Now let's stop the profiler using profiler stop. At this point, a FlameGraph image will be saved. In this specific case we have a chart dominated by Fibonacci threads:
Note that this graph is especially useful when we want to detect where our CPU time is being spent.
12. Summary
In this tutorial, we explored some of the most powerful and useful features of Arthas.
As we have seen, Arthas has many commands that can help us diagnose various problems. It can also be especially helpful when we don't have access to the code of the application we're reviewing, or if we want to quickly diagnose a problematic application running on a server.
References:
-
Official documentation: https://arthas.aliyun.com/doc/
-
Arthas GitHub warehouse address: https://github.com/alibaba/arthas