Installation and use of Arthas in mac system

Arthas is a Java diagnostic tool open source by Alibaba in September 2018. It supports JDK6 + and adopts command-line interaction mode, which can easily locate and diagnose online program operation problems. The official document of Arthas is very detailed. See: https://alibaba.github.io/arthas

Arthas usage scenario

Thanks to the powerful and rich functions of Arthas, what Arthas can do is beyond imagination. Just a few common usage cases are listed below. More usage scenarios can be explored by yourself after you are familiar with Arthas.
Is there a global perspective to view the health of the system?
Why does the CPU rise again? Where does it occupy the CPU?
Is there a deadlock in the running multithread? Is there a blockage?
The program takes a long time to run. Where does it take a long time? How to monitor?
Which jar package is this class loaded from? Why do you report all kinds of related exceptions?
Why didn't the code I changed execute? Am I not commit ted? Wrong branch?
You can't debug online when you encounter problems. Can you only republish it by adding logs?
Is there any way to monitor the real-time running status of the JVM?

1, Download Arthas boot jar

There are two official ways to download Arthas boot Jar or directly install and use as sh. The former is explained here. I download the jar package

 curl -O https://alibaba.github.io/arthas/arthas-boot.jar
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  138k  100  138k    0     0   177k      0 --:--:-- --:--:-- --:--:--  176k

2, Run Arthas boot jar

The whole arthas is developed in java language, so it can be run directly in java jar

$ java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.5.3
[INFO] Process 67746 already using port 3658
[INFO] Process 67746 already using port 8563
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 67746 springboot-mybatis-all-1.0.0.jar
  [2]: 70997 com.huohuo.service.jvm.DeadLockTest
  [3]: 70996 org.jetbrains.jps.cmdline.Launcher
  [4]: 70570
  [5]: 70798 org.jetbrains.idea.maven.server.RemoteMavenServer36
1
[INFO] arthas home: /Users/huoyajing/.arthas/lib/3.5.5/arthas
[INFO] The target process already listen port 3658, skip attach.
[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.5.5
main_class org.springframework.boot.loader.JarLauncher
pid        67746
time       2022-03-02 15:43:29

[arthas@67746]$

1) Select the jps process to monitor


You can also directly Java - jar Arthas boot Jar PID directly into the topic.

Note:[ arthas@67746 ]$indicates that you have opened the monitoring client, where you can execute relevant commands for viewing. You can use quit (exit the current client), stop\shutdown (close the Arthas server and exit all clients).
67746 is PID.

2) Visual interface operation http://127.0.0.1:8563/

In addition to viewing on the command line, it can also be accessed through the browser http://127.0.0.1:8563/ see. As shown in the following figure: you can directly operate the relevant command parameters

3, Common commands

1)help

[arthas@73120]$ help
 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 c
              ount, 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 exc
              eption of specified method invocation
 tt           Time Tunnel
 jvm          Display the target JVM information
 perfcounter  Display the perf counter information.
 ognl         Execute ognl expression.
 mc           Memory compiler, compiles java files into bytecode and class file
              s in memory.
 redefine     Redefine classes. @see Instrumentation#redefineClasses(ClassDefin
              ition...)
 retransform  Retransform classes. @see Instrumentation#retransformClasses(Clas
              s...)
 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-prof
              iler
 vmtool       jvm tool
 stop         Stop/Shutdown Arthas server and exit the console.

2) dashboard can view the running status of the whole process, including thread, memory, GC and running environment information

It mainly shows three parts: thread, jvm and Java env. It will refresh automatically every few seconds

3) Thread thread information

In fact, it is the first part of the result obtained by dashboard

thread -n num view the results of the first three threads and sort them according to CPU usage

[arthas@16645]$ thread -n 3
"Thread-0" Id=10 cpuUsage=99.16% deltaTime=199ms time=53423ms RUNNABLE
    at com.huohuo.service.jvm.ArthasTest.lambda$cpuHigh$1(ArthasTest.java:47)
    at com.huohuo.service.jvm.ArthasTest$$Lambda$1/1407343478.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)


"arthas-command-execute" Id=28 cpuUsage=0.16% deltaTime=0ms time=18ms RUNNABLE
    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:448)
    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.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)


"C1 CompilerThread2" [Internal] cpuUsage=0.13% deltaTime=0ms time=462ms

4) thread pid view the specific result of a thread

5) thread -b deadlock information without pid

[arthas@3987]$ thread -b
"Thread-1" Id=11 BLOCKED on java.lang.Object@57d20628 owned by "Thread-2" Id=12
    at com.huohuo.service.jvm.ArthasTest.lambda$deadThread$2(ArthasTest.java:68)
    -  blocked on java.lang.Object@57d20628
    -  locked java.lang.Object@7bd50b57 <---- but blocks 1 other threads!
    at com.huohuo.service.jvm.ArthasTest$$Lambda$2/2121744517.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)
```bash
[arthas@3987]$ thread 10
"Thread-0" Id=10 RUNNABLE
    at com.huohuo.service.jvm.ArthasTest.lambda$cpuHigh$1(ArthasTest.java:44)
    at com.huohuo.service.jvm.ArthasTest$$Lambda$1/1407343478.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)

We can clearly see the problem arthastest Java: there is a problem with line 44.

6) Full path decompilation of jad class

This makes it easy for us to check whether the online code is the correct version.

[arthas@3987]$ jad com.huohuo.service.jvm.ArthasTest

//These are the class loading mechanisms AppClassLoader (application class loader) and ExtClassLoader (extension class loader)
ClassLoader:
+-sun.misc.Launcher$AppClassLoader@18b4aac2
  +-sun.misc.Launcher$ExtClassLoader@7da3e221

//My project path
Location:
/Users/huoyajing/information/spring/springBoot/J2020/springboot-mybatis-all/target/classes/

//The following information is clear. It's very convenient to check whether the online code is the latest. It's very convenient

       /*
        * Decompiled with CFR.
        */
       package com.huohuo.service.jvm;

       import java.util.HashSet;

       public class ArthasTest {
           private static HashSet hashSet = new HashSet();

           public static void cpuHigh() {
               new Thread(() -> {
                   while (true) {
                       // Infinite loop
                   }
               }).start();
           }

           public static void addHashSetThread() {
               new Thread(() -> {
/*29*/             int count = 0;
                   while (true) {
                       try {
                           while (true) {
/*32*/                         hashSet.ad

......ellipsis

7) ognl can view / modify the values on the system line

ognl '@ full path category @ static attribute name' calls static attribute

[arthas@11021]$ ognl @com.huohuo.service.jvm.ArthasTest@hashSet
@HashSet[
    @String[count1],
    @String[count2],
    @String[count0],
    @String[count27],
    @String[count5],
    @String[count26],
    @String[count6],
    @String[count25],
    @String[count3],
    @String[count24],
    @String[count4],
    @String[count23],
    @String[count9],
    @String[count7],
    @String[count8],
    @String[count22],
    @String[count21],
    @String[count20],
    @String[count19],
    @String[count18],
    @String[count17],
    @String[count16],
    @String[count15],
    @String[count14],
    @String[count13],
    @String[count12],
    @String[count11],
    @String[count10],
]
[arthas@11021]$ ognl @com.huohuo.service.jvm.ArthasTest@integer
@Integer[2]

ognl '@ full path category @ static method name ("parameter")' call static method

ognl '@com.huohuo.service.jvm.ArthasTest@hashSet.add("huohuo")'

...

8) sc -d full path class information

[arthas@16645]$ sc -d com.huohuo.service.jvm.ArthasTest
 class-info        com.huohuo.service.jvm.ArthasTest
 code-source       /Users/huoyajing/information/spring/springBoot/J2020/springbo
                   ot-mybatis-all/target/classes/
 name              com.huohuo.service.jvm.ArthasTest
 isInterface       false
 isAnnotation      false
 isEnum            false
 isAnonymousClass  false
 isArray           false
 isLocalClass      false
 isMemberClass     false
 isPrimitive       false
 isSynthetic       false
 simple-name       ArthasTest
 modifier          public
 annotation
 interfaces
 super-class       +-java.lang.Object
 class-loader      +-sun.misc.Launcher$AppClassLoader@18b4aac2
                     +-sun.misc.Launcher$ExtClassLoader@7da3e221
 classLoaderHash   18b4aac2

Affect(row-cnt:1) cost in 33 ms.

For more commands, click

4, [ERROR] attach fail, targetPid: 77710

I started the java process directly from idea and run.

$ java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.5.1
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 70570
  [2]: 77709 org.jetbrains.jps.cmdline.Launcher
  [3]: 77710 com.huohuo.service.jvm.ArthasTest
3
[INFO] arthas home: /Users/huoyajing/.arthas/lib/3.5.5/arthas
[INFO] Try to attach process 77710
[WARN] Current VM java version: 13 do not match target VM java version: 1.8, attach may fail.
[WARN] Target VM JAVA_HOME is /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre, arthas-boot JAVA_HOME is /Library/Java/JavaVirtualMachines/jdk-13.0.2.jdk/Contents/Home, try to set the same JAVA_HOME.
[ERROR] Start arthas failed, exception stack trace:
com.sun.tools.attach.AgentLoadException: 0
	at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:108)
	at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:119)
	at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:147)
	at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:122)
	at com.taobao.arthas.core.Arthas.<init>(Arthas.java:27)
	at com.taobao.arthas.core.Arthas.main(Arthas.java:151)
[ERROR] attach fail, targetPid: 77710

$ java -version
java version "13.0.2" 2020-01-14
Java(TM) SE Runtime Environment (build 13.0.2+8)
Java HotSpot(TM) 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)

Then I switched the JDK version to JDK8. It's really no problem. Why is this problem? Because my Idea is executed using JDK8. iTerm started with JDK13, so the version is different. Change it to solve the problem.

Keywords: Java jvm arthas

Added by spicey on Wed, 02 Mar 2022 16:02:32 +0200