diff --git a/README.html b/README.html index 5bb85eae5..9c8863b19 100644 --- a/README.html +++ b/README.html @@ -32,6 +32,7 @@ + @@ -93,7 +94,7 @@
  • 进阶使用
  • 命令列表
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -230,6 +231,15 @@ + + + + + @@ -115,7 +116,7 @@
  • 命令列表
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -219,7 +220,7 @@
  • sc——查看JVM已加载的类信息
  • sm——查看已加载类的方法信息
  • dump——dump 已加载类的 byte code 到特定目录
  • -
  • redefine——加载外部的.class文件,redefine到JVM里
  • +
  • redefine——加载外部的.class文件,redefine到JVM里
  • jad——反编译指定已加载类的源码
  • classloader——查看classloader的继承树,urls,类加载信息,使用classloader去getResource
  • @@ -227,7 +228,7 @@

    monitor/watch/trace相关

    -
    请注意,这些命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上、预发使用时,请尽量明确需要观测的类、方法以及条件,诊断结束要执行 shutdown 或将增强过的类执行 reset 命令。
    +
    请注意,这些命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上、预发使用时,请尽量明确需要观测的类、方法以及条件,诊断结束要执行 shutdown 或将增强过的类执行 reset 命令。

    管道

    -

    Arthas支持使用管道对上述命令的结果进行进一步的处理,如sm org.apache.log4j.Logger | grep <init>

    +

    Arthas支持使用管道对上述命令的结果进行进一步的处理,如sm org.apache.log4j.Logger | grep

  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -206,8 +207,8 @@

    classloader

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

    classloader 命令将 JVM 中所有的classloader的信息统计出来,并可以展示继承树,urls等。

    -

    可以让指定的classloader去getResources,打印出所有查找到的resources的url。对于ResourceNotFoundException比较有用。

    +

    classloader 命令将 JVM 中所有的classloader的信息统计出来,并可以展示继承树,urls等。

    +

    可以让指定的classloader去getResources,打印出所有查找到的resources的url。对于ResourceNotFoundException比较有用。

    参数说明

    @@ -248,87 +249,87 @@

    使用参考

    按类加载类型查看统计信息

    -
    $ classloader
    +
    $ classloader
      name                                       numberOfInstances  loadedCountTotal
    - com.taobao.arthas.agent.ArthasClassloader  1                  2115
    - BootstrapClassLoader                       1                  1861
    - sun.reflect.DelegatingClassLoader          5                  5
    - sun.misc.Launcher$AppClassLoader           1                  4
    - sun.misc.Launcher$ExtClassLoader           1                  1
    -Affect(row-cnt:5) cost in 3 ms.
    + com.taobao.arthas.agent.ArthasClassloader  1                  2115
    + BootstrapClassLoader                       1                  1861
    + sun.reflect.DelegatingClassLoader          5                  5
    + sun.misc.Launcher$AppClassLoader           1                  4
    + sun.misc.Launcher$ExtClassLoader           1                  1
    +Affect(row-cnt:5) cost in 3 ms.
     

    按类加载实例查看统计信息

    -
    $ classloader -l
    - name                                                loadedCount  hash      parent
    - BootstrapClassLoader                                1861         null      null
    - com.taobao.arthas.agent.ArthasClassloader@68b31f0a  2115         68b31f0a  sun.misc.Launcher$ExtClassLoader@66350f69
    - sun.misc.Launcher$AppClassLoader@3d4eac69           4            3d4eac69  sun.misc.Launcher$ExtClassLoader@66350f69
    - sun.misc.Launcher$ExtClassLoader@66350f69           1            66350f69  null
    -Affect(row-cnt:4) cost in 2 ms.
    +
    $ classloader -l
    + name                                                loadedCount  hash      parent
    + BootstrapClassLoader                                1861         null      null
    + com.taobao.arthas.agent.ArthasClassloader@68b31f0a  2115         68b31f0a  sun.misc.Launcher$ExtClassLoader@66350f69
    + sun.misc.Launcher$AppClassLoader@3d4eac69           4            3d4eac69  sun.misc.Launcher$ExtClassLoader@66350f69
    + sun.misc.Launcher$ExtClassLoader@66350f69           1            66350f69  null
    +Affect(row-cnt:4) cost in 2 ms.
     

    查看ClassLoader的继承树

    -
    $ classloader -t
    +
    $ classloader -t
     +-BootstrapClassLoader
    -+-sun.misc.Launcher$ExtClassLoader@66350f69
    ++-sun.misc.Launcher$ExtClassLoader@66350f69
       +-com.taobao.arthas.agent.ArthasClassloader@68b31f0a
    -  +-sun.misc.Launcher$AppClassLoader@3d4eac69
    -Affect(row-cnt:4) cost in 3 ms.
    +  +-sun.misc.Launcher$AppClassLoader@3d4eac69
    +Affect(row-cnt:4) cost in 3 ms.
     

    查看URLClassLoader实际的urls

    -
    $ classloader -c 3d4eac69
    +
    $ classloader -c 3d4eac69
     file:/private/tmp/arthas-demo.jar
     file:/Users/hengyunabc/.arthas/lib/3.0.5/arthas/arthas-agent.jar
     
    -Affect(row-cnt:9) cost in 3 ms.
    +Affect(row-cnt:9) cost in 3 ms.
     

    使用ClassLoader去查找resource

    -
    $ classloader -c 3d4eac69  -r META-INF/MANIFEST.MF
    +
    $ classloader -c 3d4eac69  -r META-INF/MANIFEST.MF
      jar:file:/System/Library/Java/Extensions/MRJToolkit.jar!/META-INF/MANIFEST.MF
      jar:file:/private/tmp/arthas-demo.jar!/META-INF/MANIFEST.MF
      jar:file:/Users/hengyunabc/.arthas/lib/3.0.5/arthas/arthas-agent.jar!/META-INF/MANIFEST.MF
     

    也可以尝试查找类的class文件:

    -
    $ classloader -c 1b6d3586 -r java/lang/String.class
    +
    $ classloader -c 1b6d3586 -r java/lang/String.class
      jar:file:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/rt.jar!/java/lang/String.class
     

    使用ClassLoader去加载类

    -
    $ classloader -c 3d4eac69 --load demo.MathGame
    +
    $ classloader -c 3d4eac69 --load demo.MathGame
     load class success.
      class-info        demo.MathGame
      code-source       /private/tmp/arthas-demo.jar
      name              demo.MathGame
    - isInterface       false
    - isAnnotation      false
    - isEnum            false
    - isAnonymousClass  false
    - isArray           false
    - isLocalClass      false
    - isMemberClass     false
    - isPrimitive       false
    - isSynthetic       false
    + 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
    + class-loader      +-sun.misc.Launcher$AppClassLoader@3d4eac69
    +                     +-sun.misc.Launcher$ExtClassLoader@66350f69
      classLoaderHash   3d4eac69
     
    @@ -409,6 +410,15 @@ load class success. + + + + + @@ -117,7 +118,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -301,6 +302,15 @@ + + + + + @@ -94,7 +95,7 @@
  • 进阶使用
  • 命令列表
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -257,6 +258,15 @@ + + + + + @@ -122,7 +123,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -202,7 +203,7 @@

    当运行在Ali-tomcat时,会显示当前tomcat的实时信息,如HTTP请求的qps, rt, 错误数, 线程池信息等等。

    使用参考

    -
    $ dashboard
    +
    $ dashboard
     ID         NAME                              GROUP                  PRIORITY   STATE       %CPU       TIME       INTERRUPTED DAEMON
     889        RMI TCP Connection(15)-30.10.166. RMI Runtime            9          RUNNABLE    48         0:5        false       true
     1077       Timer-for-arthas-dashboard-0      system                 9          RUNNABLE    24         0:0        false       true
    @@ -235,8 +236,7 @@ java.home                                                           error/s
                                                                         received/s                        0B
     systemload.average                3.44                              sent/s                            0B
     processors                        4                                 threadpool                        http-bio-8080
    -uptime                            16020s                            busy                              0
    -
    +uptime 16020s busy 0
    @@ -248,7 +248,7 @@ uptime 16020s busy
  • PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
  • STATE: 线程的状态
  • CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
  • -
  • TIME: 线程运行总时间,数据格式为分:秒
  • +
  • TIME: 线程运行总时间,数据格式为分:秒
  • INTERRUPTED: 线程当前的中断位状态
  • DAEMON: 是否是daemon线程
  • @@ -332,6 +332,15 @@ uptime 16020s busy + + + + + @@ -121,7 +122,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -224,17 +225,17 @@

    使用参考

    -
    $ dump java.lang.String
    +
    $ 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.
    +Affect(row-cnt:1) cost in 119 ms.
     
    -
    $ dump demo.*
    +
    $ dump demo.*
      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.
    + 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.
     
    @@ -313,6 +314,15 @@ Affect(row-cnt:1) cost in + + + + + @@ -227,6 +228,15 @@ + + + + + @@ -192,7 +193,7 @@
  • help - display Arthas help
  • cls - clear the screen
  • session - display current session information
  • -
  • reset - reset all the enhanced classes. All enhanced classes will also be reset when Arthas server is closed by shutdown
  • +
  • reset - reset all the enhanced classes. All enhanced classes will also be reset when Arthas server is closed by shutdown
  • version - print the version for the Arthas attached to the current Java process
  • history - view command history
  • quit/exit - exit the current Arthas session, without effecting other sessions
  • @@ -217,15 +218,15 @@
  • sc - check the info for the classes loaded by JVM
  • sm - check methods info for the loaded classes
  • dump - dump the loaded classes in byte code to the specified location
  • -
  • redefine - load external *.class files and re-define it into JVM
  • +
  • redefine - load external *.class files and re-define it into JVM
  • jad - decompile the specified loaded classes
  • -
  • classloader - check the inheritance structure, urls, class loading info for the specified class; using classloader to get the url of the resource e.g. java/lang/String.class
  • +
  • classloader - check the inheritance structure, urls, class loading info for the specified class; using classloader to get the url of the resource e.g. java/lang/String.class
  • pipe

    -

    Arthas provides pipe to process the result returned from commands further, e.g. sm org.apache.log4j.Logger | grep <init>. Commands supported in pipe:

    +

    Arthas provides pipe to process the result returned from commands further, e.g. sm org.apache.log4j.Logger | grep . Commands supported in pipe:

    • grep - filter the result with the given keyword
    • plaintext - remove the color
    • @@ -251,9 +252,9 @@

    async in background

    -

    async can be handy when a problem is hardly to reproduce in the production environment, e.g. one watch condition may happen only once in one single day.

    +

    async can be handy when a problem is hardly to reproduce in the production environment, e.g. one watch condition may happen only once in one single day.

      -
    • job control - use > to redirect result into the log file, use & to put the job to the background. Job keeps running even if the session is disconnected (the session lifecycle is 1 day by default)
    • +
    • job control - use > to redirect result into the log file, use & to put the job to the background. Job keeps running even if the session is disconnected (the session lifecycle is 1 day by default)
    • jobs - list all jobs
    • kill - forcibly terminate the job
    • fg - bring the suspend job to the foreground
    • @@ -354,6 +355,15 @@ + + + + + @@ -201,25 +202,25 @@

      Fundamental Fields in Expressions

      -

      There is a very fundamental class Advice for the expressions used in filtering, tracing or monitoring and other aspects in commands.

      -
      public class Advice {
      +

      There is a very fundamental class Advice for the expressions used in filtering, tracing or monitoring and other aspects in commands.

      +
      public class Advice {
       
      -    private final ClassLoader loader;
      -    private final Class<?> clazz;
      -    private final ArthasMethod method;
      -    private final Object target;
      -    private final Object[] params;
      -    private final Object returnObj;
      -    private final Throwable throwExp;
      -    private final boolean isBefore;
      -    private final boolean isThrow;
      -    private final boolean isReturn;
      +    private final ClassLoader loader;
      +    private final Class<?> clazz;
      +    private final ArthasMethod method;
      +    private final Object target;
      +    private final Object[] params;
      +    private final Object returnObj;
      +    private final Throwable throwExp;
      +    private final boolean isBefore;
      +    private final boolean isThrow;
      +    private final boolean isReturn;
           
      -    // getter/setter  
      -}  
      +    // getter/setter  
      +}  
       
      -

      Description for the variables in the class Advice:

      +

      Description for the variables in the class Advice:

      @@ -348,6 +349,15 @@ + + + + + @@ -198,36 +199,36 @@

      1. Use & to run the command in the background

      For example, execute the trace command in the background:

      -
      trace Test t &  
      +
      trace Test t &  
       

      By doing this, the current command is put to the background to run, you can continue to execute other commands in the console.

      2. List background jobs

      -

      If you want to list all background jobs, you can execute the jobs command and the results are as follows:

      -
      $ jobs
      -[10]*
      -       Stopped           watch com.taobao.container.Test test "params[0].{? #this.name == null }" -x 2
      -       execution count : 19
      -       start time      : Fri Sep 22 09:59:55 CST 2017
      -       timeout date    : Sat Sep 23 09:59:55 CST 2017
      -       session         : 3648e874-5e69-473f-9eed-7f89660b079b (current)
      +

      If you want to list all background jobs, you can execute the jobs command and the results are as follows:

      +
      $ jobs
      +[10]*
      +       Stopped           watch com.taobao.container.Test test "params[0].{? #this.name == null }" -x 2
      +       execution count : 19
      +       start time      : Fri Sep 22 09:59:55 CST 2017
      +       timeout date    : Sat Sep 23 09:59:55 CST 2017
      +       session         : 3648e874-5e69-473f-9eed-7f89660b079b (current)
       

      You can see that there is currently a background job executing:

        -
      • job id is 10, * indicates that this job is created by the current session.
      • -
      • status is Stopped
      • +
      • job id is 10, * indicates that this job is created by the current session.
      • +
      • status is Stopped
      • execution count is the number of executions, which have been executed 19 times since the start.
      • timeout date: timeout timestamp, when the time exceeds this timestamp, the job will be automatically timeout and exit.

      3. Suspend and cancel job

      -

      When the job is executing in the foreground, for example, directly executing the command trace Test t, or executing the background job command trace Test t &, then putting the job back to the forground via fg command, the console cannot continue to execute other command, but can receive and process the following keyboard events:

      +

      When the job is executing in the foreground, for example, directly executing the command trace Test t, or executing the background job command trace Test t &, then putting the job back to the forground via fg command, the console cannot continue to execute other command, but can receive and process the following keyboard events:

        -
      • ‘ctrl + z’: Suspend the job, the job status will change to Stopped, and the job can be restarted by bg <job-id> or fg <job-id>
      • +
      • ‘ctrl + z’: Suspend the job, the job status will change to Stopped, and the job can be restarted by bg or fg
      • ‘ctrl + c’: Stop the job
      • ‘ctrl + d’: According to linux semantics this should lead to exit the terminal, right now Arthas has not implemented this yet, therefore simply ignore this keystroke.
      @@ -235,29 +236,29 @@

      4. fg/bg, switch the job from the foreground to the background, and vise verse

        -
      • When a job is executed in the background or in suspended status (use ctrl + z to suspend job), fg <job-id> can transfer the job to the foreground to continue to run.
      • -
      • When a job is in suspended status (use ctrl + z to suspend job), bg <job-id> can put the job to the background to continue to run.
      • -
      • A job created by other session can only be put to the foreground to run by using fg in the current session.
      • +
      • When a job is executed in the background or in suspended status (use ctrl + z to suspend job), fg can transfer the job to the foreground to continue to run.
      • +
      • When a job is in suspended status (use ctrl + z to suspend job), bg can put the job to the background to continue to run.
      • +
      • A job created by other session can only be put to the foreground to run by using fg in the current session.

      5. Redirect the output

      -

      The job output can be redirect to the specified file by > or >>, and can be used together with &. By doing this, you can achieve running commands asynchronously, for example:

      -
      $ trace Test t >> test.out &
      +

      The job output can be redirect to the specified file by > or >>, and can be used together with &. By doing this, you can achieve running commands asynchronously, for example:

      +
      $ trace Test t >> test.out &
       
      -

      The trace command will be running in the background and the output will be redirect to ~/logs/arthas-cache/test.out. You can continue to execute other commands in the console, at the same time, you can also examine the execution result from the output file.

      +

      The trace command will be running in the background and the output will be redirect to ~/logs/arthas-cache/test.out. You can continue to execute other commands in the console, at the same time, you can also examine the execution result from the output file.

      When connect to a remote Arthas server, you may not be able to view the output file on the remote machine. In this case, Arthas also supports automatically redirecting the output to the local cache file. Examples are as follows:

      -
      $ trace Test t >>  &
      -job id  : 2
      +
      $ trace Test t >>  &
      +job id  : 2
       cache location  : /Users/gehui/logs/arthas-cache/28198/2
       
      -

      If output path is not given, Arthas will automatically redirect the output to the local cache. Job id and cache location will be shown on the console. Cache location is a directory where the output files are put. For one given job, the path of its output file contains PID and job id in order to avoid potential conflict with other jobs. In the above example, pid is 28198 and job id is 2.

      +

      If output path is not given, Arthas will automatically redirect the output to the local cache. Job id and cache location will be shown on the console. Cache location is a directory where the output files are put. For one given job, the path of its output file contains PID and job id in order to avoid potential conflict with other jobs. In the above example, pid is 28198 and job id is 2.

      6. Stop job

      -

      If you want to stop background job, just kill <job-id>.

      +

      If you want to stop background job, just kill .

      7. Others

      @@ -340,6 +341,15 @@ cache location : /Users/gehui/logs/arthas-cache/28198/2 + + + + + @@ -193,10 +194,10 @@

      Usage

      Step 1: Create the script

      -

      Create a test.as script suffixed with as. Here as is suggested for the suffix of the filename, but in fact any suffix is acceptable.

      -
      ➜  arthas git:(develop) cat /var/tmp/test.as
      -help
      -dashboard -b -n 1
      +

      Create a test.as script suffixed with as. Here as is suggested for the suffix of the filename, but in fact any suffix is acceptable.

      +
      ➜  arthas git:(develop) cat /var/tmp/test.as
      +help
      +dashboard -b -n 1
       session
       thread
       sc -d org.apache.commons.lang.StringUtils
      @@ -205,21 +206,21 @@ sc -d org.apache.commons.lang.StringUtils
       

      Note:

      • Each command takes one line.
      • -
      • Batch mode (via -b) and execution times (via -n) must be explicitly specified for dashboard, otherwise batch script cannot terminate.
      • -
      • Commands such as watch/tt/trace/monitor/stack should include -n option to ensure the script can be able to quit.
      • -
      • Also consider to use async (for example: watch c.t.X test returnObj > &) to put commands run at background and get the output from the log file, see more from asynchronous job
      • +
      • Batch mode (via -b) and execution times (via -n) must be explicitly specified for dashboard, otherwise batch script cannot terminate.
      • +
      • Commands such as watch/tt/trace/monitor/stack should include -n option to ensure the script can be able to quit.
      • +
      • Also consider to use async (for example: watch c.t.X test returnObj > &) to put commands run at background and get the output from the log file, see more from asynchronous job

      Step 2: Run the script

      -

      Use -b to turn on batch mode, and use -f to specify the script file. By default the result will be output to the standard output, but you can redirect the output to the file like this:

      -
      ./as.sh -b -f /var/tmp/test.as 56328 > test.out
      +

      Use -b to turn on batch mode, and use -f to specify the script file. By default the result will be output to the standard output, but you can redirect the output to the file like this:

      +
      ./as.sh -b -f /var/tmp/test.as 56328 > test.out
       

      Step 3: Check the outputs

      -
      cat test.out
      +
      cat test.out
       
      @@ -298,6 +299,15 @@ sc -d org.apache.commons.lang.StringUtils + + + + + @@ -203,7 +204,7 @@

      classloader

      View hierarchy, urls and classes-loading info for the class-loaders.

      -

      classloader can search and print out the URLs for a specified resource from one particular classloader. It is quite handy when analyze ResourceNotFoundException.

      +

      classloader can search and print out the URLs for a specified resource from one particular classloader. It is quite handy when analyze ResourceNotFoundException.

      Options

      @@ -244,87 +245,87 @@

      Usage

      View statistics categorized by class type

      -
      $ classloader
      +
      $ classloader
        name                                       numberOfInstances  loadedCountTotal
      - com.taobao.arthas.agent.ArthasClassloader  1                  2115
      - BootstrapClassLoader                       1                  1861
      - sun.reflect.DelegatingClassLoader          5                  5
      - sun.misc.Launcher$AppClassLoader           1                  4
      - sun.misc.Launcher$ExtClassLoader           1                  1
      -Affect(row-cnt:5) cost in 3 ms.
      + com.taobao.arthas.agent.ArthasClassloader  1                  2115
      + BootstrapClassLoader                       1                  1861
      + sun.reflect.DelegatingClassLoader          5                  5
      + sun.misc.Launcher$AppClassLoader           1                  4
      + sun.misc.Launcher$ExtClassLoader           1                  1
      +Affect(row-cnt:5) cost in 3 ms.
       

      View statistics categorized by loaded classes number

      -
      $ classloader -l
      - name                                                loadedCount  hash      parent
      - BootstrapClassLoader                                1861         null      null
      - com.taobao.arthas.agent.ArthasClassloader@68b31f0a  2115         68b31f0a  sun.misc.Launcher$ExtClassLoader@66350f69
      - sun.misc.Launcher$AppClassLoader@3d4eac69           4            3d4eac69  sun.misc.Launcher$ExtClassLoader@66350f69
      - sun.misc.Launcher$ExtClassLoader@66350f69           1            66350f69  null
      -Affect(row-cnt:4) cost in 2 ms.
      +
      $ classloader -l
      + name                                                loadedCount  hash      parent
      + BootstrapClassLoader                                1861         null      null
      + com.taobao.arthas.agent.ArthasClassloader@68b31f0a  2115         68b31f0a  sun.misc.Launcher$ExtClassLoader@66350f69
      + sun.misc.Launcher$AppClassLoader@3d4eac69           4            3d4eac69  sun.misc.Launcher$ExtClassLoader@66350f69
      + sun.misc.Launcher$ExtClassLoader@66350f69           1            66350f69  null
      +Affect(row-cnt:4) cost in 2 ms.
       

      View class-loaders hierarchy

      -
      $ classloader -t
      +
      $ classloader -t
       +-BootstrapClassLoader
      -+-sun.misc.Launcher$ExtClassLoader@66350f69
      ++-sun.misc.Launcher$ExtClassLoader@66350f69
         +-com.taobao.arthas.agent.ArthasClassloader@68b31f0a
      -  +-sun.misc.Launcher$AppClassLoader@3d4eac69
      -Affect(row-cnt:4) cost in 3 ms.
      +  +-sun.misc.Launcher$AppClassLoader@3d4eac69
      +Affect(row-cnt:4) cost in 3 ms.
       

      Show the URLs of the URLClassLoader

      -
      $ classloader -c 3d4eac69
      +
      $ classloader -c 3d4eac69
       file:/private/tmp/arthas-demo.jar
       file:/Users/hengyunabc/.arthas/lib/3.0.5/arthas/arthas-agent.jar
       
      -Affect(row-cnt:9) cost in 3 ms.
      +Affect(row-cnt:9) cost in 3 ms.
       

      Use the classloader to load resource

      -
      $ classloader -c 3d4eac69  -r META-INF/MANIFEST.MF
      +
      $ classloader -c 3d4eac69  -r META-INF/MANIFEST.MF
        jar:file:/System/Library/Java/Extensions/MRJToolkit.jar!/META-INF/MANIFEST.MF
        jar:file:/private/tmp/arthas-demo.jar!/META-INF/MANIFEST.MF
        jar:file:/Users/hengyunabc/.arthas/lib/3.0.5/arthas/arthas-agent.jar!/META-INF/MANIFEST.MF
       
      -

      Use the classloader to load .class resource

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

      Use the classloader to load .class resource

      +
      $ classloader -c 1b6d3586 -r java/lang/String.class
        jar:file:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/rt.jar!/java/lang/String.class
       

      Use the classloader to load class

      -
      $ classloader -c 3d4eac69 --load demo.MathGame
      +
      $ classloader -c 3d4eac69 --load demo.MathGame
       load class success.
        class-info        demo.MathGame
        code-source       /private/tmp/arthas-demo.jar
        name              demo.MathGame
      - isInterface       false
      - isAnnotation      false
      - isEnum            false
      - isAnonymousClass  false
      - isArray           false
      - isLocalClass      false
      - isMemberClass     false
      - isPrimitive       false
      - isSynthetic       false
      + 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
      + class-loader      +-sun.misc.Launcher$AppClassLoader@3d4eac69
      +                     +-sun.misc.Launcher$ExtClassLoader@66350f69
        classLoaderHash   3d4eac69
       
      @@ -404,6 +405,15 @@ load class success. + + + + + @@ -298,6 +299,15 @@ + + + + + @@ -196,11 +197,11 @@

      dashboard

      -
      This is the real time statistics dashboard for the current system, press Ctrl+C to exit.
      +
      This is the real time statistics dashboard for the current system, press Ctrl+C to exit.

      When running in Apache Tomcat Alibaba edition, the dashboard will also present the real time statistics of the tomcat, including QPS, RT, error counts, and thread pool, etc.

      Usage

      -
      $ dashboard
      +
      $ dashboard
       ID         NAME                              GROUP                  PRIORITY   STATE       %CPU       TIME       INTERRUPTED DAEMON
       889        RMI TCP Connection(15)-30.10.166. RMI Runtime            9          RUNNABLE    48         0:5        false       true
       1077       Timer-for-arthas-dashboard-0      system                 9          RUNNABLE    24         0:0        false       true
      @@ -233,8 +234,7 @@ java.home                                                           error/s
                                                                           received/s                        0B
       systemload.average                3.44                              sent/s                            0B
       processors                        4                                 threadpool                        http-bio-8080
      -uptime                            16020s                            busy                              0
      -
      +uptime 16020s busy 0
      @@ -246,7 +246,7 @@ uptime 16020s busy
    • PRIORITY: thread priority, ranged from 1 to 10. The greater number, the higher priority
    • STATE: thread state
    • CPU%: the ratio of CPU usage for the thread, sampled every 100ms
    • -
    • TIME: total running time in minute:second format
    • +
    • TIME: total running time in minute:second format
    • INTERRUPTED: the thread interruption state
    • DAEMON: daemon thread or not
    • @@ -329,6 +329,15 @@ uptime 16020s busy + + + + + @@ -222,17 +223,17 @@

      Usage

      -
      $ dump java.lang.String
      +
      $ 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.
      +Affect(row-cnt:1) cost in 119 ms.
       
      -
      $ dump demo.*
      +
      $ dump demo.*
        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.
      + 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.
       
      @@ -310,6 +311,15 @@ Affect(row-cnt:1) cost in + + + + + @@ -233,6 +234,15 @@ + + + + + @@ -197,48 +198,48 @@
      • It is recommended to use the [OGNL] (ognl.md) command, which will be more flexibility.
      -

      Check the static fields of classes conveniently, the usage is getstatic class_name field_name.

      -
      $ getstatic demo.MathGame random
      +

      Check the static fields of classes conveniently, the usage is getstatic class_name field_name.

      +
      $ getstatic demo.MathGame random
       field: random
      -@Random[
      -    serialVersionUID=@Long[3905348978240129619],
      -    seed=@AtomicLong[120955813885284],
      -    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@2eaa1027],
      -    seedOffset=@Long[24],
      -]
      +@Random[
      +    serialVersionUID=@Long[3905348978240129619],
      +    seed=@AtomicLong[120955813885284],
      +    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@2eaa1027],
      +    seedOffset=@Long[24],
      +]
       
      -

      Tip: if the static field is a complex class, you can even use OGNL to traverse, filter and access the inner properties of this class.

      +

      Tip: if the static field is a complex class, you can even use OGNL to traverse, filter and access the inner properties of this class.

      -

      E.g. suppose n is a Map and its key is a Enum, then you can achieve this if you want to pick the key with a specific Enum value:

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

      E.g. suppose n is a Map and its key is a Enum, then you can achieve this if you want to pick the key with a specific Enum value:

      +
      $ getstatic com.alibaba.arthas.Test n 'entrySet().iterator.{? #this.key.name()=="STOP"}'
       field: n
      -@ArrayList[
      -    @Node[STOP=bbb],
      -]
      -Affect(row-cnt:1) cost in 68 ms.
      +@ArrayList[
      +    @Node[STOP=bbb],
      +]
      +Affect(row-cnt:1) cost in 68 ms.
       
      -$ getstatic com.alibaba.arthas.Test m 'entrySet().iterator.{? #this.key=="a"}'
      +$ getstatic com.alibaba.arthas.Test m 'entrySet().iterator.{? #this.key=="a"}'
       field: m
      -@ArrayList[
      -    @Node[a=aaa],
      -]
      +@ArrayList[
      +    @Node[a=aaa],
      +]
       
      @@ -315,6 +316,15 @@ field: m + + + + + @@ -169,7 +170,7 @@

      Limitations

        -
      1. Prohibit from alternating the original logic. Like watch command, The major purpose of scripting is monitoring and observing.
      2. +
      3. Prohibit from alternating the original logic. Like watch command, The major purpose of scripting is monitoring and observing.
      4. Only allow to monitor at the stages of before/success/exception/finish on one method.
      @@ -204,151 +205,151 @@ enable regex match, the default is wildcard match -

      Note: the third parameter script-filepath must be the absolute path of the groovy script, for example /tmp/test.groovy. It is not recommended to use relative path, e.g. ./test.groovy.

      +

      Note: the third parameter script-filepath must be the absolute path of the groovy script, for example /tmp/test.groovy. It is not recommended to use relative path, e.g. ./test.groovy.

      Explanation on the important callbacks

      -
      /**
      - * Listeners for script to enhance the class
      - */
      -interface ScriptListener {
      +
      /**
      + * Listeners for script to enhance the class
      + */
      +interface ScriptListener {
       
      -    /**
      -     * When the script is created
      -     *
      -     * @param output Output
      -     */
      -    void create(Output output);
      +    /**
      +     * When the script is created
      +     *
      +     * @param output Output
      +     */
      +    void create(Output output);
       
      -    /**
      -     * When the script is destroyed
      -     *
      -     * @param output Output
      -     */
      -    void destroy(Output output);
      +    /**
      +     * When the script is destroyed
      +     *
      +     * @param output Output
      +     */
      +    void destroy(Output output);
       
      -    /**
      -     * Before the method executes
      -     *
      -     * @param output Output
      -     * @param advice Advice
      -     */
      -    void before(Output output, Advice advice);
      +    /**
      +     * Before the method executes
      +     *
      +     * @param output Output
      +     * @param advice Advice
      +     */
      +    void before(Output output, Advice advice);
       
      -    /**
      -     * After the method returns
      -     *
      -     * @param output Output
      -     * @param advice Advice
      -     */
      -    void afterReturning(Output output, Advice advice);
      +    /**
      +     * After the method returns
      +     *
      +     * @param output Output
      +     * @param advice Advice
      +     */
      +    void afterReturning(Output output, Advice advice);
       
      -    /**
      -     * After the method throws exceptions
      -     *
      -     * @param output Output
      -     * @param advice Advice
      -     */
      -    void afterThrowing(Output output, Advice advice);
      +    /**
      +     * After the method throws exceptions
      +     *
      +     * @param output Output
      +     * @param advice Advice
      +     */
      +    void afterThrowing(Output output, Advice advice);
       
      -}
      +}
       
      -

      Advice parameter

      -

      Advice contains all information necessary for notification. Refer to expression core parameters for more details.

      +

      Advice parameter

      +

      Advice contains all information necessary for notification. Refer to expression core parameters for more details.

      -

      Output parameter

      -

      There are three methods in Output, used for outputting the corresponding text.

      -
      /**
      - * Output
      - */
      -interface Output {
      +

      Output parameter

      +

      There are three methods in Output, used for outputting the corresponding text.

      +
      /**
      + * Output
      + */
      +interface Output {
       
      -    /**
      -     * Output text without line break
      -     *
      -     * @param string Text to output
      -     * @return this
      -     */
      -    Output print(String string);
      +    /**
      +     * Output text without line break
      +     *
      +     * @param string Text to output
      +     * @return this
      +     */
      +    Output print(String string);
       
      -    /**
      -     * Output text with line break
      -     *
      -     * @param string Text to output
      -     * @return this
      -     */
      -    Output println(String string);
      +    /**
      +     * Output text with line break
      +     *
      +     * @param string Text to output
      +     * @return this
      +     */
      +    Output println(String string);
       
      -    /**
      -     * Finish outputting from the script
      -     *
      -     * @return this
      -     */
      -    Output finish();
      +    /**
      +     * Finish outputting from the script
      +     *
      +     * @return this
      +     */
      +    Output finish();
       
      -}
      +}
       

      A groovy sample script to output logs

      -
      import com.taobao.arthas.core.command.ScriptSupportCommand
      -import com.taobao.arthas.core.util.Advice
      +
      import com.taobao.arthas.core.command.ScriptSupportCommand
      +import com.taobao.arthas.core.util.Advice
       
      -import static java.lang.String.format
      +import static java.lang.String.format
       
      -/**
      - * Output method logs
      - */
      -public class Logger implements ScriptSupportCommand.ScriptListener {
      +/**
      + * Output method logs
      + */
      +public class Logger implements ScriptSupportCommand.ScriptListener {
       
      -    @Override
      -    void create(ScriptSupportCommand.Output output) {
      -        output.println("script create.");
      -    }
      +    @Override
      +    void create(ScriptSupportCommand.Output output) {
      +        output.println("script create.");
      +    }
       
      -    @Override
      -    void destroy(ScriptSupportCommand.Output output) {
      -        output.println("script destroy.");
      -    }
      +    @Override
      +    void destroy(ScriptSupportCommand.Output output) {
      +        output.println("script destroy.");
      +    }
       
      -    @Override
      -    void before(ScriptSupportCommand.Output output, Advice advice) {
      -        output.println(format("before:class=%s;method=%s;paramslen=%d;%s;",
      -                advice.getClazz().getSimpleName(),
      -                advice.getMethod().getName(),
      -                advice.getParams().length, advice.getParams()))
      -    }
      +    @Override
      +    void before(ScriptSupportCommand.Output output, Advice advice) {
      +        output.println(format("before:class=%s;method=%s;paramslen=%d;%s;",
      +                advice.getClazz().getSimpleName(),
      +                advice.getMethod().getName(),
      +                advice.getParams().length, advice.getParams()))
      +    }
       
      -    @Override
      -    void afterReturning(ScriptSupportCommand.Output output, Advice advice) {
      -        output.println(format("returning:class=%s;method=%s;",
      -                advice.getClazz().getSimpleName(),
      -                advice.getMethod().getName()))
      -    }
      +    @Override
      +    void afterReturning(ScriptSupportCommand.Output output, Advice advice) {
      +        output.println(format("returning:class=%s;method=%s;",
      +                advice.getClazz().getSimpleName(),
      +                advice.getMethod().getName()))
      +    }
       
      -    @Override
      -    void afterThrowing(ScriptSupportCommand.Output output, Advice advice) {
      -        output.println(format("throwing:class=%s;method=%s;",
      -                advice.getClazz().getSimpleName(),
      -                advice.getMethod().getName()))
      -    }
      -}
      +    @Override
      +    void afterThrowing(ScriptSupportCommand.Output output, Advice advice) {
      +        output.println(format("throwing:class=%s;method=%s;",
      +                advice.getClazz().getSimpleName(),
      +                advice.getMethod().getName()))
      +    }
      +}
       

      Run the script like this:

      -
      $ groovy com.alibaba.sample.petstore.dal.dao.ProductDao getProductById /Users/zhuyong/middleware/arthas/scripts/Logger.groovy -S
      +
      $ groovy com.alibaba.sample.petstore.dal.dao.ProductDao getProductById /Users/zhuyong/middleware/arthas/scripts/Logger.groovy -S
       script create.
       Press Ctrl+C to abort.
      -Affect(class-cnt:1 , method-cnt:1) cost in 102 ms.
      -before:class=IbatisProductDao;method=getProductById;paramslen=1;[Ljava.lang.Object;@45df64fc;
      -returning:class=IbatisProductDao;method=getProductById;
      -before:class=IbatisProductDao;method=getProductById;paramslen=1;[Ljava.lang.Object;@5b0e2d00;
      -returning:class=IbatisProductDao;method=getProductById;
      +Affect(class-cnt:1 , method-cnt:1) cost in 102 ms.
      +before:class=IbatisProductDao;method=getProductById;paramslen=1;[Ljava.lang.Object;@45df64fc;
      +returning:class=IbatisProductDao;method=getProductById;
      +before:class=IbatisProductDao;method=getProductById;paramslen=1;[Ljava.lang.Object;@5b0e2d00;
      +returning:class=IbatisProductDao;method=getProductById;
       
      @@ -417,6 +418,15 @@ returning:class=IbatisProductDao;< + + + + + @@ -279,6 +280,15 @@ + + + + + @@ -91,8 +92,8 @@
      • Installation
        • Quick installation
        • Full installation
        • @@ -180,36 +181,36 @@

          Quick installation

          -

          Use arthas-boot(Recommend)

          -

          Downloadarthas-boot.jar,Start with java command:

          -
          $ wget https://alibaba.github.io/arthas/arthas-boot.jar
          +

          Use arthas-boot(Recommend)

          +

          Downloadarthas-boot.jar,Start with java command:

          +
          $ wget https://alibaba.github.io/arthas/arthas-boot.jar
           $ java -jar arthas-boot.jar
           

          Print usage:

          -
          $ java -jar arthas-boot.jar -h
          +
          $ java -jar arthas-boot.jar -h
           
          -

          Use as.sh

          +

          Use as.sh

          You can install Arthas with one single line command on Linux, Unix, and Mac. Pls. copy the following command and paste it into the command line, then press Enter to run:

          -
          $ curl -L https://alibaba.github.io/arthas/install.sh | sh
          +
          $ curl -L https://alibaba.github.io/arthas/install.sh | sh
           
          -

          The command above will download the bootstrap script as.sh to the current directory. You can move it the any other place you want, or put its location in $PATH.

          -

          You can enter its interactive interface by executing as.sh, or execute as.sh -h for more help information.

          +

          The command above will download the bootstrap script as.sh to the current directory. You can move it the any other place you want, or put its location in $PATH.

          +

          You can enter its interactive interface by executing as.sh, or execute as.sh -h for more help information.

          Full installation

          Latest Version, Click To Download: Arthas

          -

          Download and unzip, find arthas-boot.jar in the directory. Start with java command:

          -
          $ java -jar arthas-boot.jar
          +

          Download and unzip, find arthas-boot.jar in the directory. Start with java command:

          +
          $ java -jar arthas-boot.jar
           

          Print usage:

          -
          $ java -jar arthas-boot.jar -h
          +
          $ java -jar arthas-boot.jar -h
           
          @@ -225,11 +226,11 @@ $ java -jar arthas-boot.jar

          Uninstall

          • On Linux/Unix/Mac, delete the files with the following command:

            -
            $ rm -rf ~/.arthas/
            +
            $ rm -rf ~/.arthas/
             
          • -
          • On Windows, delete .arthas directory under user home.

            +
          • On Windows, delete .arthas directory under user home.

          @@ -307,6 +308,15 @@ $ java -jar arthas-boot.jar + + + + + @@ -106,7 +107,7 @@
        • jad
          • Options
          • Usage @@ -201,7 +202,7 @@

            jad

            Decompile the specified classes.
            -

            jad helps to decompile the byte code running in JVM to the source code to assist you to understand the logic behind better.

            +

            jad helps to decompile the byte code running in JVM to the source code to assist you to understand the logic behind better.

            • The decompiled code is syntax highlighted for better readability in Arthas console.
            • It is possible that there’s grammar error in the decompiled code, but it should not affect your interpretation.
            • @@ -233,41 +234,41 @@

              Usage

              -

              Decompile java.lang.String

              -
              $ jad java.lang.String
              +

              Decompile java.lang.String

              +
              $ jad java.lang.String
               
              -ClassLoader:
              +ClassLoader:
               
              -Location:
              +Location:
               
              -/*
              -* Decompiled with CFR 0_132.
              -*/
              -package java.lang;
              +/*
              +* Decompiled with CFR 0_132.
              +*/
              +package java.lang;
               
              -import java.io.ObjectStreamField;
              -...
              -public final class String
              -implements Serializable,
              -Comparable<String>,
              -CharSequence {
              -    private final char[] value;
              -    private int hash;
              -    private static final long serialVersionUID = -6849794470754667710L;
              -    private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
              -    public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
              +import java.io.ObjectStreamField;
              +...
              +public final class String
              +implements Serializable,
              +Comparable<String>,
              +CharSequence {
              +    private final char[] value;
              +    private int hash;
              +    private static final long serialVersionUID = -6849794470754667710L;
              +    private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
              +    public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
               
              -    public String(byte[] arrby, int n, int n2) {
              -        String.checkBounds(arrby, n, n2);
              -        this.value = StringCoding.decode(arrby, n, n2);
              -    }
              -...
              +    public String(byte[] arrby, int n, int n2) {
              +        String.checkBounds(arrby, n, n2);
              +        this.value = StringCoding.decode(arrby, n, n2);
              +    }
              +...
               

              Decompile the specified method

              -
              $ jad demo.MathGame main
              +
              $ jad demo.MathGame main
               
               ClassLoader:
               +-sun.misc.Launcher$AppClassLoader@3d4eac69
              @@ -291,23 +292,23 @@ Affect(row-cnt:1) cost in 228 ms.
               

              Decompile with specified classLoader

              -
              If the target class is loaded by multiple classloaders, jad outputs the hashcode of the corresponding classloaders, then you can re-run jad and specify -c <hashcode> to decompile the target class from the specified classloader.
              -
              $ jad org.apache.log4j.Logger
              +
              If the target class is loaded by multiple classloaders, jad outputs the hashcode of the corresponding classloaders, then you can re-run jad and specify -c to decompile the target class from the specified classloader.
              +
              $ jad org.apache.log4j.Logger
               
               Found more than one class for: org.apache.log4j.Logger, Please use jad -c hashcode org.apache.log4j.Logger
               HASHCODE  CLASSLOADER
              -69dcaba4  +-monitor's ModuleClassLoader
              +69dcaba4  +-monitor's ModuleClassLoader
               6e51ad67  +-java.net.URLClassLoader@6e51ad67
                           +-sun.misc.Launcher$AppClassLoader@6951a712
                           +-sun.misc.Launcher$ExtClassLoader@6fafc4c2
              -2bdd9114  +-pandora-qos-service's ModuleClassLoader
              -4c0df5f8  +-pandora-framework's ModuleClassLoader
              +2bdd9114  +-pandora-qos-service's ModuleClassLoader
              +4c0df5f8  +-pandora-framework's ModuleClassLoader
               
               Affect(row-cnt:0) cost in 38 ms.
               $ jad org.apache.log4j.Logger -c 69dcaba4
               
               ClassLoader:
              -+-monitor's ModuleClassLoader
              ++-monitor's ModuleClassLoader
               
               Location:
               /Users/admin/app/log4j-1.2.14.jar
              @@ -406,6 +407,15 @@ Affect(row-cnt:1) cost in 190 ms.
               
               
               
              +
              +
              +
              +
               
              +
                
               
               
              @@ -199,7 +200,7 @@
               
              Check the current JVM’s info

              Usage

              -
              $ jvm
              +
              $ jvm
                CATEGORY            INFO
               ------------------------------------------------------------------------------------------------------------------------------------
               
              @@ -284,8 +285,7 @@
                
                                     MAX-FILE-DESCRIPTOR-COUNT  10240
                                     OPEN-FILE-DESCRIPTOR-COUNT 648
              -Affect cost in 2 ms.
              -
              +Affect cost in 2 ms.
        • Call static method:

          -
          $ ognl '@java.lang.System@out.println("hello")'
          +
          $ ognl '@java.lang.System@out.println("hello")'
           null
           

          Get static field:

          -
          $ 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],
          -]
          +
          $ 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],
          +]
           

          Execute a multi-line expression, and return a 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],
          -]
          +
          $ 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],
          +]
           
          @@ -342,6 +343,15 @@ null + + + + + @@ -248,11 +249,10 @@

          Usage

          For example, to enable saving command execution result, input the command below:

          -
          $ options save-result true                                                                                         
          +
          $ options save-result true                                                                                         
            NAME         BEFORE-VALUE  AFTER-VALUE                                                                            
           ----------------------------------------                                                                           
          - save-result  false         true
          -
          + save-result false true
          @@ -329,6 +329,15 @@ + + + + + @@ -97,7 +98,7 @@
      • 3. Check the Dashboard
      • -
      • 4. Get the Main Class of the arthas-demo process with the thread command
      • +
      • 4. Get the Main Class of the arthas-demo process with the thread command
      • 5. Decompile Main Class with jad command
      • 6. watch
      • 7. Exit Arthas
      • @@ -180,47 +181,47 @@

        Quick Start

        1. Start Demo Application

        -
        $ wget https://alibaba.github.io/arthas/arthas-demo.jar
        +
        $ wget https://alibaba.github.io/arthas/arthas-demo.jar
         $ java -jar arthas-demo.jar
         
        -

        arthas-demo is a simple program that generates a random number every second, then find all prime factors of the number.

        -

        The source code of arthas-demo: View

        +

        arthas-demo is a simple program that generates a random number every second, then find all prime factors of the number.

        +

        The source code of arthas-demo: View

        2. Start Arthas

        Linux/Unix/Mac

        Execute the following command in the command line:

        -
        $ wget https://alibaba.github.io/arthas/arthas-boot.jar
        +
        $ wget https://alibaba.github.io/arthas/arthas-boot.jar
         $ java -jar arthas-boot.jar
         
          -
        • The user to run this command MUST have the same privilege as the owner of the target process, as a simple example you can try the following command if the target process is managed by user admin: sudo su admin && java -jar arthas-boot.jar or sudo -u admin -EH java -jar arthas-boot.jar
        • -
        • .If you cannot be able to attach to the target process, please check the logs under ~/logs/arthas for troubleshooting.
        • -
        • java -jar arthas-boot.jar -h print usage.
        • +
        • The user to run this command MUST have the same privilege as the owner of the target process, as a simple example you can try the following command if the target process is managed by user admin: sudo su admin && java -jar arthas-boot.jar or sudo -u admin -EH java -jar arthas-boot.jar
        • +
        • If you cannot be able to attach to the target process, please check the logs under ~/logs/arthas for troubleshooting.
        • +
        • java -jar arthas-boot.jar -h print usage.

        Select the target Java process to attach:

        -
        $ $ java -jar arthas-boot.jar
        -* [1]: 35542
        -  [2]: 71560 arthas-demo.jar
        +
        $ $ java -jar arthas-boot.jar
        +* [1]: 35542
        +  [2]: 71560 arthas-demo.jar
         

        The ‘Demo’ process is the fourth as shown above, press ‘2’ then ‘Enter’. Arthas will attach to the target process, and start to output:

        -
        [INFO] Try to attach process 71560
        -[INFO] Attach process 71560 success.
        -[INFO] arthas-client connect 127.0.0.1 3658
        +
        [INFO] Try to attach process 71560
        +[INFO] Attach process 71560 success.
        +[INFO] arthas-client connect 127.0.0.1 3658
           ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
        - /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
        -|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
        -|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
        -`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
        + /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
        +|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
        +|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
        +`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
         
         wiki: https://alibaba.github.io/arthas
        -version: 3.0.5.20181127201536
        -pid: 71560
        -time: 2018-11-28 19:16:24
        +version: 3.0.5.20181127201536
        +pid: 71560
        +time: 2018-11-28 19:16:24
         
         $
         
        @@ -229,8 +230,8 @@ $

        3. Check the Dashboard

        -

        Type ‘dashboard’ and hit ‘ENTER’, a brief report on the current process will be shown as below, pls. Ctrl+C to stop:

        -
        $ dashboard
        +

        Type ‘dashboard’ and hit ‘ENTER’, a brief report on the current process will be shown as below, pls. Ctrl+C to stop:

        +
        $ dashboard
         ID     NAME                   GROUP          PRIORI STATE  %CPU    TIME   INTERRU DAEMON
         17     pool-2-thread-1        system         5      WAITIN 67      0:0    false   false
         27     Timer-for-arthas-dashb system         10     RUNNAB 32      0:0    false   true
        @@ -265,15 +266,15 @@ java.home              /Library/Java/JavaVir
         
        -

        4. Get the Main Class of the arthas-demo process with the thread command

        -
        $ thread -n -1 | grep 'main('
        -    at demo.MathGame.main(MathGame.java:17)
        +

        4. Get the Main Class of the arthas-demo process with the thread command

        +
        $ thread -n -1 | grep 'main('
        +    at demo.MathGame.main(MathGame.java:17)
         

        5. Decompile Main Class with jad command

        -
        $ jad demo.MathGame
        +
        $ jad demo.MathGame
         
         ClassLoader:
         +-sun.misc.Launcher$AppClassLoader@3d4eac69
        @@ -322,9 +323,9 @@ public class MathGame {
                 Iterator<Integer> iterator = primeFactors.iterator();
                 while (iterator.hasNext()) {
                     int factor = iterator.next();
        -            sb.append(factor).append('*');
        +            sb.append(factor).append('*');
                 }
        -        if (sb.charAt(sb.length() - 1) == '*') {
        +        if (sb.charAt(sb.length() - 1) == '*') {
                     sb.deleteCharAt(sb.length() - 1);
                 }
                 System.out.println(sb);
        @@ -356,8 +357,8 @@ Affect(row-cnt:1) cost in 970 ms.
         

        6. watch

        -

        Use ‘watch’ to view the return object of demo.MathGame#primeFactors:

        -
        $ watch demo.MathGame primeFactors returnObj
        +

        Use ‘watch’ to view the return object of demo.MathGame#primeFactors:

        +
        $ watch demo.MathGame primeFactors returnObj
         Press Ctrl+C to abort.
         Affect(class-cnt:1 , method-cnt:1) cost in 107 ms.
         ts=2018-11-28 19:22:30; [cost=1.715367ms] result=null
        @@ -393,8 +394,8 @@ ts=2018-11-28 19:22:35; [cost=29.969732ms] result=@ArrayList[
         

        7. Exit Arthas

        -

        Use quit or exit to disconnect from the current process. The Arthas instance attached to the target process continues to live inside the process, and its port is standby for further connection.

        -

        Use shutdown to have Arthas completely quit from the target process.

        +

        Use quit or exit to disconnect from the current process. The Arthas instance attached to the target process continues to live inside the process, and its port is standby for further connection.

        +

        Use shutdown to have Arthas completely quit from the target process.

        @@ -470,6 +471,15 @@ ts=2018-11-28 19:22:35; [cost=29.969732ms] result=@ArrayList[ + + + + + @@ -195,7 +196,7 @@

        redefine

        -
        Load the external *.class files to re-define the loaded peer class in JVM.
        +
        Load the external *.class files to re-define the loaded peer class in JVM.

        Reference: Instrumentation#redefineClasses

        Notes: Re-defined classes cannot be restored. There are chances that redefining may fail due to some reasons, for example: there’s new field introduced in the new version of the class, pls. refer to JDK’s documentation for the limitations.
        @@ -221,9 +222,8 @@

        Usage

        -
        redefine -p /tmp/Test.class
        -redefine -c 327a647b -p /tmp/Test.class /tmp/Test$Inner.class
        -
        +
        redefine -p /tmp/Test.class
        +redefine -c 327a647b -p /tmp/Test.class /tmp/Test$Inner.class
        @@ -300,6 +300,15 @@ redefine -c 327a647b -p /tmp/Test.class /tmp/Test$Inner.class + + + + + @@ -206,17 +207,17 @@

        v2017-11-03

          -
        • [improvement] add getstatic
        • +
        • [improvement] add getstatic
        • [bug] fix Arthas class loader logs loading issues
        • -
        • [improvement] introduce OGNL to customize classloader to invoke static methods
        • -
        • [improvement] optimise termd uppercase output performance
        • -
        • [improvement] classloader compile in class loader category by default
        • -
        • [bug] fix wc counting issue
        • -
        • [improvement] disable certain JDK classes e.g. Classloader, Method, Integer and the lik
        • +
        • [improvement] introduce OGNL to customize classloader to invoke static methods
        • +
        • [improvement] optimise termd uppercase output performance
        • +
        • [improvement] classloader compile in class loader category by default
        • +
        • [bug] fix wc counting issue
        • +
        • [improvement] disable certain JDK classes e.g. Classloader, Method, Integer and the lik
        • [improvement] quit directly when encountering incorrect OGNL expression
        • -
        • [bug] fix pipe issues
        • +
        • [bug] fix pipe issues
        • [improvement] optimize command re-direct features using asynchronous log
        • -
        • [improvement] trace can filter JDK method calls
        • +
        • [improvement] trace can filter JDK method calls
        @@ -229,15 +230,15 @@

        v2017-09-11

          -
        • [improvement] async supported
        • -
        • [improvement] optimize jad support JDK 8 and inner class
        • +
        • [improvement] async supported
        • +
        • [improvement] optimize jad support JDK 8 and inner class
        • [bug] fix Chinese encoding issues

        v2017-05-11

          -
        • [improvement] tt investigating/recording level one to avoid too much performance overhead
        • +
        • [improvement] tt investigating/recording level one to avoid too much performance overhead
        • [bug] fix Chinese characters can not be presented issue
        @@ -250,31 +251,31 @@

        v2016-12-09

          -
        • [feature] as.sh support -h to print help info
        • +
        • [feature] as.sh support -h to print help info
        • [bug] [#121] fix leftover temp files causing Arthas cannot start issue
        • -
        • [bug] [#123] fix attach/shutdown repeatedly causing Arthas classloader leakage issue
        • +
        • [bug] [#123] fix attach/shutdown repeatedly causing Arthas classloader leakage issue
        • [improvement] make the help info more readable
        • [bug] [#126] fix the documents links issues
        • -
        • [bug] [#122] fix the classloader filtering out sun.reflect.DelegatingClassLoader issue
        • -
        • [bug] [#129] fix classloader presenting structure issues
        • +
        • [bug] [#122] fix the classloader filtering out sun.reflect.DelegatingClassLoader issue
        • +
        • [bug] [#129] fix classloader presenting structure issues
        • [improvement] [#125] make the Arthas log output more readable
        • -
        • [improvement] [#96] sc and more commands are supporting format as com/taobao/xxx/TestClass
        • -
        • [bug] [#124] fix the negative values of trace
        • -
        • [improvement] [#128] the output of tt will auto-expand now
        • +
        • [improvement] [#96] sc and more commands are supporting format as com/taobao/xxx/TestClass
        • +
        • [bug] [#124] fix the negative values of trace
        • +
        • [improvement] [#128] the output of tt will auto-expand now
        • [bug] [#130] providing more meaningful error messages when port conflicts
        • [bug] [#98] fix Arthas starting issue: when updating/downloading failed, Arthas will fail to start
        • [bug] [#139] fix agent attaching fails under some scenarios issues
        • -
        • [improvement] [#156] delay jd-core-java initialization to avoid Arthas starting failure
        • +
        • [improvement] [#156] delay jd-core-java initialization to avoid Arthas starting failure
        • [bug] avoid thread names duplicate issue
        • -
        • [improvement] [#150] filtering by total time cost in trace
        • -
        • [bug] fix sc NPE issue when searching SystemClassloader
        • +
        • [improvement] [#150] filtering by total time cost in trace
        • +
        • [bug] fix sc NPE issue when searching SystemClassloader
        • [bug] [#180] fix attach fails issues: attaching succeed at the first time, delete the Arthas installer, re-compile and package => attaching fails

        v2016-06-07

          -
        • [bug] fix NPE when loading spy as resource
        • +
        • [bug] fix NPE when loading spy as resource
        • [improvement] locating the blocking thread
        • [improvement] print out thread in name order
        • [improvement] specify the refreshing interval when checking topN busiest threads
        • @@ -283,22 +284,22 @@

          v2016-04-08

            -
          • [feature] specify refreshing interval and execution times in dashboard
          • +
          • [feature] specify refreshing interval and execution times in dashboard
          • [feature] log the command execution result
          • [feature] speed up the booting and attaching while the first attaching is even quicker by 100% than before
          • [feature] batch supported; script supported
          • [feature] interactive mode used in Arthas
          • -
          • [feature] inheritance relation included in class searching; global option disable-sub-class can be used to turn it off
          • +
          • [feature] inheritance relation included in class searching; global option disable-sub-class can be used to turn it off
          • [feature] colorful and plain text modes both supported
          • -
          • [improvement] merge exit and quit commands
          • +
          • [improvement] merge exit and quit commands
          • [improvement] help info enclosed with wiki links
          • -
          • [improvement] optimize watch using flow for better UX
          • -
          • [improvement] add examples to thread
          • +
          • [improvement] optimize watch using flow for better UX
          • +
          • [improvement] add examples to thread
          • [improvement] auto-completion ignores character case
          • [improvement] make the UI more beautiful/friendly
          • -
          • [bug] fix trace printing too much encountering loop issues
          • -
          • [bug] fix trace node twisting issues when method throwing exceptions
          • -
          • [bug] fix injected/enhanced BootstrapClassLoader cannot locate spy issues
          • +
          • [bug] fix trace printing too much encountering loop issues
          • +
          • [bug] fix trace node twisting issues when method throwing exceptions
          • +
          • [bug] fix injected/enhanced BootstrapClassLoader cannot locate spy issues
          @@ -312,8 +313,8 @@

          v2016-01-18

            -
          • [improvement] optimise jad; dump memory byte array in real time; using jd-core-java to decompile; line number presented;
          • -
          • [bug] fix checking/re-producing issues when tt is watching thread-context related methods invoking
          • +
          • [improvement] optimise jad; dump memory byte array in real time; using jd-core-java to decompile; line number presented;
          • +
          • [bug] fix checking/re-producing issues when tt is watching thread-context related methods invoking
          @@ -323,7 +324,7 @@
        • [bug] watch/monitor NPE
        • [bug] wrong escaping issues
        • [bug] wrong statistics
        • -
        • [bug] sc checking internal structure issues
        • +
        • [bug] sc checking internal structure issues
        @@ -404,6 +405,15 @@ + + + + + @@ -165,10 +166,10 @@

        reset

        -
        Reset all classes that have been enhanced by Arthas. These enhanced classes will also be reset when Arthas server is shutdown.
        +
        Reset all classes that have been enhanced by Arthas. These enhanced classes will also be reset when Arthas server is shutdown.

        Usage

        -
        $ reset -h
        +
        $ reset -h
          USAGE:
            reset [-h] [-E] [class-pattern]
         
        @@ -183,13 +184,12 @@
          OPTIONS:
          -h, --help                                                         this help
          -E, --regex                                                        Enable regular expression to match (wildcard matching by default)
        - <class-pattern>                                                    Path and classname of Pattern Matching
        -
        + <class-pattern> Path and classname of Pattern Matching

        Reset specified class

        -
        $ trace Test test
        +
        $ trace Test test
         Press Ctrl+C to abort.
         Affect(class-cnt:1 , method-cnt:1) cost in 57 ms.
         `---ts=2017-10-26 17:10:33;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@14dad5dc
        @@ -199,21 +199,19 @@ Affect(class-cnt:1 , method-cnt:1) cost in 57 ms.
             `---[0.068692ms] Test:test()
         
         $ reset Test
        -Affect(class-cnt:1 , method-cnt:0) cost in 11 ms.
        -
        +Affect(class-cnt:1 , method-cnt:0) cost in 11 ms.

        Reset all classes

        -
        $ trace Test test
        +
        $ trace Test test
         Press Ctrl+C to abort.
         Affect(class-cnt:1 , method-cnt:1) cost in 15 ms.
         `---ts=2017-10-26 17:12:06;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@14dad5dc
             `---[0.128518ms] Test:test()
         
         $ reset
        -Affect(class-cnt:1 , method-cnt:0) cost in 9 ms.
        -
        +Affect(class-cnt:1 , method-cnt:0) cost in 9 ms.
        @@ -281,6 +279,15 @@ Affect(class-cnt:1 , method-cnt:0) cost in 9 ms. + + + + + @@ -192,30 +193,30 @@
        Log command outputs for later analysis
        • By default, this behavior is turned off. To enable it, execute the command below:

          -
          $ options save-result true
          +
          $ options save-result true
            NAME         BEFORE-VALUE  AFTER-VALUE
           ----------------------------------------
          -save-result  false         true
          -Affect(row-cnt:1) cost in 3 ms.
          +save-result  false         true
          +Affect(row-cnt:1) cost in 3 ms.
           

          If the message above is output on the console, then this behavior is enabled successfully.

        • Log file path

          -

          The command execution result will be save in {user.home}/logs/arthas-cache/result.log. Pls. clean it up regularly to save disk space.

          +

          The command execution result will be save in {user.home}/logs/arthas-cache/result.log. Pls. clean it up regularly to save disk space.

        Use asynchronous job to log

        -
        $ trace Test t >>  &
        -job id  : 2
        +
        $ trace Test t >>  &
        +job id  : 2
         cache location  : /Users/zhuyong/logs/arthas-cache/28198/2
         
        -

        By doing this, the command will run at background asynchronously, and output the execution result into ~/logs/arthas-cache/{PID}/{JobId}:

        +

        By doing this, the command will run at background asynchronously, and output the execution result into ~/logs/arthas-cache/{PID}/{JobId}:

        • The background job will continue to run even if the current session is disconnected. The default job timeout value is 1 day, use global ‘options’ command to alternate it.
        • -
        • The execution result will be output into the file asynchronously. Pls. note the behavior of this command is not controlled by save-result option from global options. No matter save-result is set to true or not, this command will write into ~/logs/arthas-cache/{PID}/{JobId} anyway, instead of into ~/logs/arthas-cache/result.log.
        • +
        • The execution result will be output into the file asynchronously. Pls. note the behavior of this command is not controlled by save-result option from global options. No matter save-result is set to true or not, this command will write into ~/logs/arthas-cache/{PID}/{JobId} anyway, instead of into ~/logs/arthas-cache/result.log.
        @@ -292,6 +293,15 @@ cache location : /Users/zhuyong/logs/arthas-cache/28198/2 + + + + + @@ -196,7 +197,7 @@

        sc

        Search classes loaded by JVM.
        -

        sc stands for search class. This command can search all possible classes loaded by JVM and show their information. The supported options are: [d]、[E]、[f] and [x:].

        +

        sc stands for search class. This command can search all possible classes loaded by JVM and show their information. The supported options are: [d]、[E]、[f] and [x:].

        Supported Options

        @@ -234,78 +235,78 @@
        class-patten supports full qualified class name, e.g. com.taobao.test.AAA and com/taobao/test/AAA. It also supports the format of ‘com/taobao/test/AAA’, so that it is convenient to directly copy class name from the exception stack trace without replacing ‘/’ to ‘.’.

        -sc turns on matching sub-class match by default, that is, sc will also search the sub classes of the target class too. If exact-match is desired, pls. use options disable-sub-class true.
        +sc turns on matching sub-class match by default, that is, sc will also search the sub classes of the target class too. If exact-match is desired, pls. use options disable-sub-class true.

        Usage

        • Wildcards match search

          -
          $ sc demo.*
          +
          $ sc demo.*
           demo.MathGame
          -Affect(row-cnt:1) cost in 55 ms.
          +Affect(row-cnt:1) cost in 55 ms.
           
        • View class details

          -
          $ sc -d demo.MathGame
          +
          $ sc -d demo.MathGame
           class-info        demo.MathGame
           code-source       /private/tmp/arthas-demo.jar
           name              demo.MathGame
          -isInterface       false
          -isAnnotation      false
          -isEnum            false
          -isAnonymousClass  false
          -isArray           false
          -isLocalClass      false
          -isMemberClass     false
          -isPrimitive       false
          -isSynthetic       false
          +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
          +class-loader      +-sun.misc.Launcher$AppClassLoader@3d4eac69
          +                    +-sun.misc.Launcher$ExtClassLoader@66350f69
           classLoaderHash   3d4eac69
           
          -Affect(row-cnt:1) cost in 875 ms.
          +Affect(row-cnt:1) cost in 875 ms.
           
        • View class fileds

          -
          $ sc -d -f demo.MathGame
          +
          $ sc -d -f demo.MathGame
           class-info        demo.MathGame
           code-source       /private/tmp/arthas-demo.jar
           name              demo.MathGame
          -isInterface       false
          -isAnnotation      false
          -isEnum            false
          -isAnonymousClass  false
          -isArray           false
          -isLocalClass      false
          -isMemberClass     false
          -isPrimitive       false
          -isSynthetic       false
          +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
          +class-loader      +-sun.misc.Launcher$AppClassLoader@3d4eac69
          +                    +-sun.misc.Launcher$ExtClassLoader@66350f69
           classLoaderHash   3d4eac69
           fields            modifierprivate,static
          -                  type    java.util.Random
          +                  type    java.util.Random
                             name    random
                             value   java.util.Random@522b4
                                     08a
           
                             modifierprivate
          -                  type    int
          +                  type    int
                             name    illegalArgumentCount
           
          -Affect(row-cnt:1) cost in 19 ms.
          +Affect(row-cnt:1) cost in 19 ms.
           
        • @@ -385,6 +386,15 @@ Affect(row-cnt:1) cost in + + + + + @@ -245,6 +246,15 @@ + + + + + @@ -196,7 +197,7 @@

          sm

          Search method from the loaded classes.
          -

          sm stands for search method. This command can search and show method information from all loaded classes. sm can only view the methods declared on the target class, that is, methods from its parent classes are invisible.

          +

          sm stands for search method. This command can search and show method information from all loaded classes. sm can only view the methods declared on the target class, that is, methods from its parent classes are invisible.

          Options

          @@ -227,8 +228,8 @@

          Usage

          -

          View methods of java.lang.String:

          -
          $ sm java.lang.String
          +

          View methods of java.lang.String:

          +
          $ sm java.lang.String
           java.lang.String-><init>
           java.lang.String->equals
           java.lang.String->toString
          @@ -273,20 +274,20 @@ java.lang.String->toCharArray
           java.lang.String->format
           java.lang.String->copyValueOf
           java.lang.String->intern
          -Affect(row-cnt:44) cost in 1342 ms.
          +Affect(row-cnt:44) cost in 1342 ms.
           
          -

          View method java.lang.String#toString details:

          -
          $ sm -d java.lang.String toString
          +

          View method java.lang.String#toString details:

          +
          $ sm -d java.lang.String toString
            declaring-class  java.lang.String
            method-name      toString
            modifier         public
            annotation
            parameters
          - return           java.lang.String
          + return           java.lang.String
            exceptions
           
          -Affect(row-cnt:1) cost in 3 ms.
          +Affect(row-cnt:1) cost in 3 ms.
           
          @@ -364,6 +365,15 @@ Affect(row-cnt:1) cost in + + + + + @@ -202,7 +203,7 @@

          stack

          Print out the full call stack of the current method.
          -

          Most often we know one method gets called, but we have no idea on which code path gets executed or when the method gets called since there are so many code paths to the target method. The command stack comes to rescue in this difficult situation.

          +

          Most often we know one method gets called, but we have no idea on which code path gets executed or when the method gets called since there are so many code paths to the target method. The command stack comes to rescue in this difficult situation.

          Parameters

          @@ -234,8 +235,8 @@ -
          execution times

          There’s one thing worthy noting here is observation expression. The observation expression supports OGNL grammar, for example, you can come up a expression like this "{params,returnObj}". All OGNL expressions are supported as long as they are legal to the grammar.

          -

          Thanks for advice’s data structure, it is possible to observe from varieties of different angles. Inside advice parameter, all necessary information for notification can be found.

          +

          There’s one thing worthy noting here is observation expression. The observation expression supports OGNL grammar, for example, you can come up a expression like this "{params,returnObj}". All OGNL expressions are supported as long as they are legal to the grammar.

          +

          Thanks for advice’s data structure, it is possible to observe from varieties of different angles. Inside advice parameter, all necessary information for notification can be found.

          Pls. refer to core parameters in expression for more details.

          • Pls. also refer to https://github.com/alibaba/arthas/issues/71 for more advanced usage
          • @@ -246,44 +247,44 @@

            Usage

            Start Demo

            -

            Start arthas-demo in Quick Start.

            +

            Start arthas-demo in Quick Start.

            stack

            -
            $ stack demo.MathGame primeFactors
            +
            $ 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)
            +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)
             

            Filtering by condition expression

            -
            $ stack demo.MathGame primeFactors 'params[0]<0' -n 2
            +
            $ stack demo.MathGame primeFactors 'params[0]<0' -n 2
             Press Ctrl+C to abort.
            -Affect(class-cnt:1 , method-cnt:1) cost in 30 ms.
            -ts=2018-12-04 01:34:27;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)
            +Affect(class-cnt:1 , method-cnt:1) cost in 30 ms.
            +ts=2018-12-04 01:34:27;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)
             
            -ts=2018-12-04 01:34:30;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)
            +ts=2018-12-04 01:34:30;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)
             
            -Command execution times exceed limit: 2, so command will exit. You can set it with -n option.
            +Command execution times exceed limit: 2, so command will exit. You can set it with -n option.
             

            Filtering by cost

            -
            $ stack demo.MathGame primeFactors '#cost>5'
            +
            $ 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)
            +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)
             
            @@ -362,6 +363,15 @@ Affect(class-cnt:1 , method-cnt:1) + + + + + @@ -166,20 +167,20 @@

            Start Arthas

            Interactive Mode

            -
            ./as.sh
            +
            ./as.sh
             
            -
            ➜  bin git:(develop) ✗ ./as.sh
            +
            ➜  bin git:(develop) ✗ ./as.sh
             Found existing java process, please choose one and hit RETURN.
            -  [1]: 3088 org.jetbrains.idea.maven.server.RemoteMavenServer
            -* [2]: 12872 org.apache.catalina.startup.Bootstrap
            -  [3]: 2455
            -Attaching to 12872...
            +  [1]: 3088 org.jetbrains.idea.maven.server.RemoteMavenServer
            +* [2]: 12872 org.apache.catalina.startup.Bootstrap
            +  [3]: 2455
            +Attaching to 12872...
               ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
            - /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
            -|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
            -|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
            -`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
            + /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
            +|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
            +|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
            +`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
             $
             
            @@ -187,14 +188,14 @@ $

            Non-Interactive Mode

            Startup script is as follows:

            -
            ./as.sh <PID>[@IP:PORT]
            +
            ./as.sh <PID>[@IP:PORT]
             

            Parameter Description

            • PID: Target Java process ID (Make sure that the user executing the command has sufficient permissions to operate the target Java process.)
            • -
            • IP: The address that Arthas Server listens on, the default value is 127.0.0.1. Arthas allows multiple users to access simultaneously without interfering with each other.
            • +
            • IP: The address that Arthas Server listens on, the default value is 127.0.0.1. Arthas allows multiple users to access simultaneously without interfering with each other.
            • PORT: Arthas Server port,the default value is 3658
            @@ -214,22 +215,22 @@ $

            Remote Diagnosis

            -

            After starting Arthas Server on the target Java process, users can use telnet connect to the remote Arthas Server, for example:

            -
            telnet 192.168.1.119 3658
            +

            After starting Arthas Server on the target Java process, users can use telnet connect to the remote Arthas Server, for example:

            +
            telnet 192.168.1.119 3658
             

            sudo Support

            -

            Usually online environment will only grant users privilege as low as possible, instead, all advanced operations are through sudo-list. Since as.sh script takes into account the current effective user, it is possible to run the script in the other rule, by specifying -H option like this:

            -
            sudo -u admin -H ./as.sh 12345
            +

            Usually online environment will only grant users privilege as low as possible, instead, all advanced operations are through sudo-list. Since as.sh script takes into account the current effective user, it is possible to run the script in the other rule, by specifying -H option like this:

            +
            sudo -u admin -H ./as.sh 12345
             

            Windows Support

            -

            Right now as.bat script supports one parameter only, which is: pid

            -
            as.bat <pid>
            +

            Right now as.bat script supports one parameter only, which is: pid

            +
            as.bat <pid>
             
            @@ -299,6 +300,15 @@ $ + + + + + @@ -201,27 +202,26 @@
            View the current JVM environment variables.

            Usage

            -
             USAGE:
            -   sysenv [-h] [env-name]
            +
             USAGE:
            +   sysenv [-h] [env-name]
             
            - SUMMARY:
            -   Display the system env.
            + SUMMARY:
            +   Display the system env.
             
            - EXAMPLES:
            -   sysenv
            -   sysenv USER
            + EXAMPLES:
            +   sysenv
            +   sysenv USER
             
            - WIKI:
            -   https://alibaba.github.io/arthas/sysenv
            + WIKI:
            +   https://alibaba.github.io/arthas/sysenv
             
            - OPTIONS:
            - -h, --help                                                 this help
            - <env-name>                                                 env name
            -
            + OPTIONS: + -h, --help this help + <env-name> env name

            View all environment variables

            -
            $ sysenv
            +
            $ sysenv
              KEY                      VALUE
             ----------------------------------------------------------------------------------------------------------------------------
              PATH                     /Users/admin/.sdkman/candidates/visualvm/current/bin:/Users/admin/.sdkman/candidates/ja
            @@ -253,17 +253,15 @@
              COLORFGBG                7;0
              HOME                     /Users/admin
              SHLVL                    1
            - AUTOJUMP_ERROR_PATH      /Users/admin/Library/autojump/errors.log
            -
            + AUTOJUMP_ERROR_PATH /Users/admin/Library/autojump/errors.log

            View individual environment variables

            -
            Use tab for auto-completion
            -
            $ sysenv USER
            -USER=admin
            -
            +
            Use tab for auto-completion
            +
            $ sysenv USER
            +USER=admin
            @@ -341,6 +339,15 @@ USER=admin + + + + + @@ -202,29 +203,28 @@
            Examine the system properties from the target JVM

            Usage

            -
             USAGE:
            -   sysprop [-h] [property-name] [property-value]
            +
             USAGE:
            +   sysprop [-h] [property-name] [property-value]
             
            - SUMMARY:
            -   Display, and change all the system properties.
            + SUMMARY:
            +   Display, and change all the system properties.
             
            - EXAMPLES:
            - sysprop
            - sysprop file.encoding
            - sysprop production.mode true
            + EXAMPLES:
            + sysprop
            + sysprop file.encoding
            + sysprop production.mode true
             
            - WIKI:
            -   https://alibaba.github.io/arthas/sysprop
            + WIKI:
            +   https://alibaba.github.io/arthas/sysprop
             
            - OPTIONS:
            - -h, --help                                  this help
            - <property-name>                             property name
            - <property-value>                            property value
            -
            + OPTIONS: + -h, --help this help + <property-name> property name + <property-value> property value

            Check all properties

            -
            $ sysprop
            +
            $ sysprop
              KEY                                                  VALUE
             -------------------------------------------------------------------------------------------------------------------------------------
              java.runtime.name                                    Java(TM) SE Runtime Environment
            @@ -293,27 +293,25 @@
              java.vendor.url.bug                                  http://bugreport.sun.com/bugreport/
              sun.cpu.endian                                       little
              sun.io.unicode.encoding                              UnicodeBig
            - sun.cpu.isalist
            -
            + sun.cpu.isalist

            Check One Single Property

            -
            Use tab for auto-completion
            -
            $ sysprop java.version
            -java.version=1.8.0_51
            +
            Use tab for auto-completion
            +
            $ sysprop java.version
            +java.version=1.8.0_51
             

            Modify Single Property

            -
            $ sysprop user.country
            +
            $ sysprop user.country
             user.country=US
             $ sysprop user.country CN
             Successfully changed the system property.
            -user.country=CN
            -
            +user.country=CN
            @@ -391,6 +389,15 @@ user.country=CN + + + + + @@ -232,142 +233,142 @@
            How the CPU ratios are calculated?

            -CPU ratio for a given thread is the CPU time it takes divided by the total CPU time within a specified interval period. It is calculated in the following way: sample CPU times for all the thread by calling java.lang.management.ThreadMXBean#getThreadCpuTime first, then sleep for a period (the default value is 100ms, which can be specified by -i), then sample CPU times again. By this, we can get the time cost for this period for each thread, then come up with the ratio.

            -Note: this operation consumes CPU time too (getThreadCpuTime is time-consuming), therefore it is possible to observe Arthas’s thread appears in the list. To avoid this, try to increase sample interval, for example: 5000 ms.

            +CPU ratio for a given thread is the CPU time it takes divided by the total CPU time within a specified interval period. It is calculated in the following way: sample CPU times for all the thread by calling java.lang.management.ThreadMXBean#getThreadCpuTime first, then sleep for a period (the default value is 100ms, which can be specified by -i), then sample CPU times again. By this, we can get the time cost for this period for each thread, then come up with the ratio.

            +Note: this operation consumes CPU time too (getThreadCpuTime is time-consuming), therefore it is possible to observe Arthas’s thread appears in the list. To avoid this, try to increase sample interval, for example: 5000 ms.

            If you’d like to check the CPU ratios from the very beginning of the Java process, show-busy-java-threads can come to help.

            Usage

            List the top n busiest threads with detailed stack trace

            -
            $ thread -n 3
            -"as-command-execute-daemon" Id=29 cpuUsage=75% RUNNABLE
            -    at sun.management.ThreadImpl.dumpThreads0(Native Method)
            -    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
            -    at com.taobao.arthas.core.command.monitor200.ThreadCommand$1.action(ThreadCommand.java:58)
            -    at com.taobao.arthas.core.command.handler.AbstractCommandHandler.execute(AbstractCommandHandler.java:238)
            -    at com.taobao.arthas.core.command.handler.DefaultCommandHandler.handleCommand(DefaultCommandHandler.java:67)
            -    at com.taobao.arthas.core.server.ArthasServer$4.run(ArthasServer.java:276)
            -    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
            -    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
            -    at java.lang.Thread.run(Thread.java:745)
            +
            $ thread -n 3
            +"as-command-execute-daemon" Id=29 cpuUsage=75% RUNNABLE
            +    at sun.management.ThreadImpl.dumpThreads0(Native Method)
            +    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
            +    at com.taobao.arthas.core.command.monitor200.ThreadCommand$1.action(ThreadCommand.java:58)
            +    at com.taobao.arthas.core.command.handler.AbstractCommandHandler.execute(AbstractCommandHandler.java:238)
            +    at com.taobao.arthas.core.command.handler.DefaultCommandHandler.handleCommand(DefaultCommandHandler.java:67)
            +    at com.taobao.arthas.core.server.ArthasServer$4.run(ArthasServer.java:276)
            +    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
            +    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
            +    at java.lang.Thread.run(Thread.java:745)
             
            -    Number of locked synchronizers = 1
            -    - java.util.concurrent.ThreadPoolExecutor$Worker@6cd0b6f8
            +    Number of locked synchronizers = 1
            +    - java.util.concurrent.ThreadPoolExecutor$Worker@6cd0b6f8
             
            -"as-session-expire-daemon" Id=25 cpuUsage=24% TIMED_WAITING
            -    at java.lang.Thread.sleep(Native Method)
            -    at com.taobao.arthas.core.server.DefaultSessionManager$2.run(DefaultSessionManager.java:85)
            +"as-session-expire-daemon" Id=25 cpuUsage=24% TIMED_WAITING
            +    at java.lang.Thread.sleep(Native Method)
            +    at com.taobao.arthas.core.server.DefaultSessionManager$2.run(DefaultSessionManager.java:85)
             
            -"Reference Handler" Id=2 cpuUsage=0% WAITING on java.lang.ref.Reference$Lock@69ba0f27
            -    at java.lang.Object.wait(Native Method)
            -    -  waiting on java.lang.ref.Reference$Lock@69ba0f27
            -    at java.lang.Object.wait(Object.java:503)
            -    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
            +"Reference Handler" Id=2 cpuUsage=0% WAITING on java.lang.ref.Reference$Lock@69ba0f27
            +    at java.lang.Object.wait(Native Method)
            +    -  waiting on java.lang.ref.Reference$Lock@69ba0f27
            +    at java.lang.Object.wait(Object.java:503)
            +    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
             

            List all threads’ info when no options provided

            -
            $ thread
            -Threads Total: 16, NEW: 0, RUNNABLE: 7, BLOCKED: 0, WAITING: 5, TIMED_WAITING: 4, TERMINATED: 0
            +
            $ thread
            +Threads Total: 16, NEW: 0, RUNNABLE: 7, BLOCKED: 0, WAITING: 5, TIMED_WAITING: 4, TERMINATED: 0
             ID         NAME                             GROUP                 PRIORITY   STATE      %CPU       TIME       INTERRUPTE DAEMON
            -30         as-command-execute-daemon        system                9          RUNNABLE   72         0:0        false      true
            -23         as-session-expire-daemon         system                9          TIMED_WAIT 27         0:0        false      true
            -22         Attach Listener                  system                9          RUNNABLE   0          0:0        false      true
            -11         pool-2-thread-1                  main                  5          TIMED_WAIT 0          0:0        false      false
            -12         Thread-2                         main                  5          RUNNABLE   0          0:0        false      true
            -13         pool-3-thread-1                  main                  5          TIMED_WAIT 0          0:0        false      false
            -25         as-selector-daemon               system                9          RUNNABLE   0          0:0        false      true
            -14         Thread-3                         main                  5          TIMED_WAIT 0          0:0        false      false
            -26         pool-5-thread-1                  system                5          WAITING    0          0:0        false      false
            -15         Thread-4                         main                  5          RUNNABLE   0          0:0        false      false
            -1          main                             main                  5          WAITING    0          0:2        false      false
            -2          Reference Handler                system                10         WAITING    0          0:0        false      true
            -3          Finalizer                        system                8          WAITING    0          0:0        false      true
            -4          Signal Dispatcher                system                9          RUNNABLE   0          0:0        false      true
            -20         NonBlockingInputStreamThread     main                  5          WAITING    0          0:0        false      true
            -21         Thread-8                         main                  5          RUNNABLE   0          0:0        false      true
            +30         as-command-execute-daemon        system                9          RUNNABLE   72         0:0        false      true
            +23         as-session-expire-daemon         system                9          TIMED_WAIT 27         0:0        false      true
            +22         Attach Listener                  system                9          RUNNABLE   0          0:0        false      true
            +11         pool-2-thread-1                  main                  5          TIMED_WAIT 0          0:0        false      false
            +12         Thread-2                         main                  5          RUNNABLE   0          0:0        false      true
            +13         pool-3-thread-1                  main                  5          TIMED_WAIT 0          0:0        false      false
            +25         as-selector-daemon               system                9          RUNNABLE   0          0:0        false      true
            +14         Thread-3                         main                  5          TIMED_WAIT 0          0:0        false      false
            +26         pool-5-thread-1                  system                5          WAITING    0          0:0        false      false
            +15         Thread-4                         main                  5          RUNNABLE   0          0:0        false      false
            +1          main                             main                  5          WAITING    0          0:2        false      false
            +2          Reference Handler                system                10         WAITING    0          0:0        false      true
            +3          Finalizer                        system                8          WAITING    0          0:0        false      true
            +4          Signal Dispatcher                system                9          RUNNABLE   0          0:0        false      true
            +20         NonBlockingInputStreamThread     main                  5          WAITING    0          0:0        false      true
            +21         Thread-8                         main                  5          RUNNABLE   0          0:0        false      true
             

            thread id, show the running stack for the target thread

            -
            $ thread 1
            -"main" Id=1 WAITING on java.util.concurrent.CountDownLatch$Sync@29fafb28
            -    at sun.misc.Unsafe.park(Native Method)
            -    -  waiting on java.util.concurrent.CountDownLatch$Sync@29fafb28
            -    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            -    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
            -    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
            -    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
            -    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
            +
            $ thread 1
            +"main" Id=1 WAITING on java.util.concurrent.CountDownLatch$Sync@29fafb28
            +    at sun.misc.Unsafe.park(Native Method)
            +    -  waiting on java.util.concurrent.CountDownLatch$Sync@29fafb28
            +    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            +    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
            +    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
            +    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
            +    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
             

            thread -b, locate the thread bocking the others

            -

            In some occasions, we experience the whole application is stuck because there’s one particular thread hold one lock that other threads are relying on. To diagnose such an issue, Arthas provides thread -b to find the problematic thread in one single command.

            -
            $ thread -b
            -"http-bio-8080-exec-4" Id=27 TIMED_WAITING
            -    at java.lang.Thread.sleep(Native Method)
            -    at test.arthas.TestThreadBlocking.doGet(TestThreadBlocking.java:22)
            -    -  locked java.lang.Object@725be470 <---- but blocks 4 other threads!
            -    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
            -    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
            -    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
            -    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
            -    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
            -    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
            -    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
            -    at test.filter.TestDurexFilter.doFilter(TestDurexFilter.java:46)
            -    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
            -    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
            -    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
            -    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
            -    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
            -    at com.taobao.tomcat.valves.ContextLoadFilterValve$FilterChainAdapter.doFilter(ContextLoadFilterValve.java:191)
            -    at com.taobao.eagleeye.EagleEyeFilter.doFilter(EagleEyeFilter.java:81)
            -    at com.taobao.tomcat.valves.ContextLoadFilterValve.invoke(ContextLoadFilterValve.java:150)
            -    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
            -    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
            -    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
            -    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:429)
            -    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
            -    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
            -    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
            +

            In some occasions, we experience the whole application is stuck because there’s one particular thread hold one lock that other threads are relying on. To diagnose such an issue, Arthas provides thread -b to find the problematic thread in one single command.

            +
            $ thread -b
            +"http-bio-8080-exec-4" Id=27 TIMED_WAITING
            +    at java.lang.Thread.sleep(Native Method)
            +    at test.arthas.TestThreadBlocking.doGet(TestThreadBlocking.java:22)
            +    -  locked java.lang.Object@725be470 <---- but blocks 4 other threads!
            +    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
            +    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
            +    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
            +    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
            +    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
            +    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
            +    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
            +    at test.filter.TestDurexFilter.doFilter(TestDurexFilter.java:46)
            +    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
            +    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
            +    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
            +    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
            +    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
            +    at com.taobao.tomcat.valves.ContextLoadFilterValve$FilterChainAdapter.doFilter(ContextLoadFilterValve.java:191)
            +    at com.taobao.eagleeye.EagleEyeFilter.doFilter(EagleEyeFilter.java:81)
            +    at com.taobao.tomcat.valves.ContextLoadFilterValve.invoke(ContextLoadFilterValve.java:150)
            +    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
            +    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
            +    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
            +    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:429)
            +    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
            +    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
            +    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
                 -  locked org.apache.tomcat.util.net.SocketWrapper@7127ee12
            -    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            -    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            -    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            -    at java.lang.Thread.run(Thread.java:745)
            +    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            +    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            +    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            +    at java.lang.Thread.run(Thread.java:745)
             
            -    Number of locked synchronizers = 1
            -    - java.util.concurrent.ThreadPoolExecutor$Worker@31a6493e
            +    Number of locked synchronizers = 1
            +    - java.util.concurrent.ThreadPoolExecutor$Worker@31a6493e
             
            -
            Note: By now Arthas only supports to locate the thread blocked by synchronzied, while java.util.concurrent.Lock is not supported yet.
            +
            Note: By now Arthas only supports to locate the thread blocked by synchronzied, while java.util.concurrent.Lock is not supported yet.

            thread -i, specify the sampling interval

            -
            $ thread -n 3 -i 1000
            -"as-command-execute-daemon" Id=4759 cpuUsage=23% RUNNABLE
            -    at sun.management.ThreadImpl.dumpThreads0(Native Method)
            -    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
            -    at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:133)
            -    at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:79)
            -    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:96)
            -    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:27)
            -    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:125)
            -    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:122)
            -    at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:332)
            -    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:756)
            +
            $ thread -n 3 -i 1000
            +"as-command-execute-daemon" Id=4759 cpuUsage=23% RUNNABLE
            +    at sun.management.ThreadImpl.dumpThreads0(Native Method)
            +    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
            +    at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:133)
            +    at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:79)
            +    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:96)
            +    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:27)
            +    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:125)
            +    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:122)
            +    at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:332)
            +    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:756)
             
            -    Number of locked synchronizers = 1
            -    - java.util.concurrent.ThreadPoolExecutor$Worker@546aeec1
            +    Number of locked synchronizers = 1
            +    - java.util.concurrent.ThreadPoolExecutor$Worker@546aeec1
             ...
             
            @@ -447,6 +448,15 @@ ID NAME GROUP PRIORITY STA + + + + + @@ -203,7 +204,7 @@

            trace

            Trace method calling path, and output the time cost for each node in the path.
            -

            trace can track the calling path specified by class-pattern / method-pattern, and calculate the time cost on the whole path.

            +

            trace can track the calling path specified by class-pattern / method-pattern, and calculate the time cost on the whole path.

            Parameters

            @@ -239,73 +240,73 @@ -
            time cost

            There’s one thing worthy noting here is observation expression. The observation expression supports OGNL grammar, for example, you can come up a expression like this "{params,returnObj}". All OGNL expressions are supported as long as they are legal to the grammar.

            -

            Thanks for advice’s data structure, it is possible to observe from varieties of different angles. Inside advice parameter, all necessary information for notification can be found.

            +

            There’s one thing worthy noting here is observation expression. The observation expression supports OGNL grammar, for example, you can come up a expression like this "{params,returnObj}". All OGNL expressions are supported as long as they are legal to the grammar.

            +

            Thanks for advice’s data structure, it is possible to observe from varieties of different angles. Inside advice parameter, all necessary information for notification can be found.

            Pls. refer to core parameters in expression for more details.

            -

            Many times what we are interested is the exact trace result when the method call takes time over one particular period. It is possible to achieve this in Arthas, for example: trace *StringUtils isBlank '#cost>100' means trace result will only be output when the executing time exceeds 100ms.

            +

            Many times what we are interested is the exact trace result when the method call takes time over one particular period. It is possible to achieve this in Arthas, for example: trace *StringUtils isBlank '#cost>100' means trace result will only be output when the executing time exceeds 100ms.

            -
            watch/stack/trace, these three commands all support #cost.
            +
            watch/stack/trace, these three commands all support #cost.

            Notice

            -

            trace is handy to help discovering and locating the performance flaws in your system, but pls. note Arthas can only trace the first level method call each time.

            +

            trace is handy to help discovering and locating the performance flaws in your system, but pls. note Arthas can only trace the first level method call each time.

            Usage

            Start Demo

            -

            Start arthas-demo in Quick Start.

            +

            Start arthas-demo in Quick Start.

            trace method

            -
            $ trace demo.MathGame run
            +
            $ trace demo.MathGame run
             Press Ctrl+C to abort.
            -Affect(class-cnt:1 , method-cnt:1) cost in 42 ms.
            -`---ts=2018-12-04 00:44:17;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
            -    `---[10.611029ms] demo.MathGame:run()
            -        +---[0.05638ms] java.util.Random:nextInt()
            -        +---[10.036885ms] demo.MathGame:primeFactors()
            -        `---[0.170316ms] demo.MathGame:print()
            +Affect(class-cnt:1 , method-cnt:1) cost in 42 ms.
            +`---ts=2018-12-04 00:44:17;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
            +    `---[10.611029ms] demo.MathGame:run()
            +        +---[0.05638ms] java.util.Random:nextInt()
            +        +---[10.036885ms] demo.MathGame:primeFactors()
            +        `---[0.170316ms] demo.MathGame:print()
             

            Ignore jdk method

            -
            $ trace -j  demo.MathGame run
            +
            $ trace -j  demo.MathGame run
             Press Ctrl+C to abort.
            -Affect(class-cnt:1 , method-cnt:1) cost in 31 ms.
            -`---ts=2018-12-04 01:09:14;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
            -    `---[5.190646ms] demo.MathGame:run()
            -        +---[4.465779ms] demo.MathGame:primeFactors()
            -        `---[0.375324ms] demo.MathGame:print()
            +Affect(class-cnt:1 , method-cnt:1) cost in 31 ms.
            +`---ts=2018-12-04 01:09:14;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
            +    `---[5.190646ms] demo.MathGame:run()
            +        +---[4.465779ms] demo.MathGame:primeFactors()
            +        `---[0.375324ms] demo.MathGame:print()
             
              -
            • -j: jdkMethodSkip, skip jdk method trace
            • +
            • -j: jdkMethodSkip, skip jdk method trace

            Filtering by cost

            -
            $ trace demo.MathGame run '#cost > 10'
            +
            $ 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()
            +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()
             
            -
            Only the call path which’s time cost is higher than 10ms will be shown. This feature is handy to focus on what’s needed to focus when troubleshoot.
            +
            Only the call path which’s time cost is higher than 10ms will be shown. This feature is handy to focus on what’s needed to focus when troubleshoot.
              -
            • Here Arthas provides the similar functionality JProfile and other commercial software provide. Compared to these professional softwares, Arthas doesn’t deduce the time cost trace itself takes, therefore it is not as accurate as these softwares offer. More classes and methods on the calling path, more inaccurate trace output is, but it is still helpful for diagnostics where the bottleneck is.
            • -
            • “[12.033735ms]” means the method on the node takes 12.033735 ms.
            • -
            • “[min=0.005428ms,max=0.094064ms,total=0.105228ms,count=3] demo:call()” means aggregating all same method calls into one single line. The minimum time cost is 0.005428 ms, the maximum time cost is 0.094064 ms, and the total time cost for all method calls (3 times in total) to “demo:call()” is 0.105228ms. If “throws Exception” appears in this line, it means some exceptions have been thrown from this method calls.
            • +
            • Here Arthas provides the similar functionality JProfile and other commercial software provide. Compared to these professional softwares, Arthas doesn’t deduce the time cost trace itself takes, therefore it is not as accurate as these softwares offer. More classes and methods on the calling path, more inaccurate trace output is, but it is still helpful for diagnostics where the bottleneck is.
            • +
            • “[12.033735ms]” means the method on the node takes 12.033735 ms.
            • +
            • “[min=0.005428ms,max=0.094064ms,total=0.105228ms,count=3] demo:call()” means aggregating all same method calls into one single line. The minimum time cost is 0.005428 ms, the maximum time cost is 0.094064 ms, and the total time cost for all method calls (3 times in total) to “demo:call()” is 0.105228ms. If “throws Exception” appears in this line, it means some exceptions have been thrown from this method calls.
            • The total time cost may not equal to the sum of the time costs each sub method call takes, this is because Arthas instrumented code takes time too.
            @@ -384,6 +385,15 @@ Affect(class-cnt:1 , method-cnt:1) + + + + + @@ -201,36 +202,36 @@

            tt

            -

            Check the parameters, return values and exceptions of the methods at different times.

            -

            watch is a powerful command but due to its feasibility and complexity, it’s quite hard to locate the issue effectively.

            -

            In such difficulties, tt comes into play.

            -

            With the help of tt (TimeTunnel), you can check the contexts of the methods at different times in execution history.

            +

            Check the parameters, return values and exceptions of the methods at different times.

            +

            watch is a powerful command but due to its feasibility and complexity, it’s quite hard to locate the issue effectively.

            +

            In such difficulties, tt comes into play.

            +

            With the help of tt (TimeTunnel), you can check the contexts of the methods at different times in execution history.

            Usage

            Start Demo

            -

            Start arthas-demo in Quick Start.

            +

            Start arthas-demo in Quick Start.

            Record method calls

            -
            $ tt -t demo.MathGame primeFactors
            +
            $ tt -t demo.MathGame primeFactors
             Press Ctrl+C to abort.
            -Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
            - INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
            +Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
            + INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
             -------------------------------------------------------------------------------------------------------------------------------------
            - 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
            + 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
             
              -
            • -t

              -

              record the calling context of the method demo.MathGame primeFactors

              +
            • -t

              +

              record the calling context of the method demo.MathGame primeFactors

            • -
            • -n 3

              -

              limit the number of the records (avoid overflow for too many records; with -n option, Arthas can automatically stop recording once the records reach the specified limit)

              +
            • -n 3

              +

              limit the number of the records (avoid overflow for too many records; with -n option, Arthas can automatically stop recording once the records reach the specified limit)

            • Property

            • @@ -281,9 +282,9 @@ Affect(class-cnt:1 , method-cnt:1)

            Tips:

              -
            1. tt -t *Test print params[0].length==1 with different amounts of parameters;
            2. -
            3. tt -t *Test print 'params[1] instanceof Integer' with different types of parameters;
            4. -
            5. tt -t *Test print params[0].mobile=="13989838402" with specified parameter.
            6. +
            7. tt -t *Test print params[0].length==1 with different amounts of parameters;
            8. +
            9. tt -t *Test print 'params[1] instanceof Integer' with different types of parameters;
            10. +
            11. tt -t *Test print params[0].mobile=="13989838402" with specified parameter.

            Advanced:

            @@ -296,33 +297,33 @@ Affect(class-cnt:1 , method-cnt:1)

            List all records

            -
            $ tt -l
            - INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
            +
            $ tt -l
            + INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
             -------------------------------------------------------------------------------------------------------------------------------------
            - 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
            -                              9
            - 1005    2018-12-04 11:15:43  0.4776    false   true     0x4b67cf4d     MathGame                       primeFactors
            -Affect(row-cnt:6) cost in 4 ms.
            + 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
            +                              9
            + 1005    2018-12-04 11:15:43  0.4776    false   true     0x4b67cf4d     MathGame                       primeFactors
            +Affect(row-cnt:6) cost in 4 ms.
             

            Searching for records

            -
            $ tt -s 'method.name=="primeFactors"'
            - INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
            +
            $ tt -s 'method.name=="primeFactors"'
            + INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
             -------------------------------------------------------------------------------------------------------------------------------------
            - 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
            - 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
            -                              9
            - 1005    2018-12-04 11:15:43  0.4776    false   true     0x4b67cf4d     MathGame                       primeFactors
            -Affect(row-cnt:6) cost in 607 ms.
            + 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
            + 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
            +                              9
            + 1005    2018-12-04 11:15:43  0.4776    false   true     0x4b67cf4d     MathGame                       primeFactors
            +Affect(row-cnt:6) cost in 607 ms.
             

            Advanced:

            @@ -334,53 +335,53 @@ Affect(row-cnt:6) cost in

            Check context of the call

            -

            Using tt -i <index> to check a specific calling details.

            -
            $ tt -i 1003
            - INDEX            1003
            - GMT-CREATE       2018-12-04 11:15:41
            - COST(ms)         0.186073
            +

            Using tt -i to check a specific calling details.

            +
            $ tt -i 1003
            + INDEX            1003
            + GMT-CREATE       2018-12-04 11:15:41
            + COST(ms)         0.186073
              OBJECT           0x4b67cf4d
              CLASS            demo.MathGame
              METHOD           primeFactors
            - IS-RETURN        false
            - IS-EXCEPTION     true
            - PARAMETERS[0]    @Integer[-564322413]
            - THROW-EXCEPTION  java.lang.IllegalArgumentException: number is: -564322413, need >= 2
            -                    at demo.MathGame.primeFactors(MathGame.java:46)
            -                    at demo.MathGame.run(MathGame.java:24)
            -                    at demo.MathGame.main(MathGame.java:16)
            + IS-RETURN        false
            + IS-EXCEPTION     true
            + PARAMETERS[0]    @Integer[-564322413]
            + THROW-EXCEPTION  java.lang.IllegalArgumentException: number is: -564322413, need >= 2
            +                    at demo.MathGame.primeFactors(MathGame.java:46)
            +                    at demo.MathGame.run(MathGame.java:24)
            +                    at demo.MathGame.main(MathGame.java:16)
             
            -Affect(row-cnt:1) cost in 11 ms.
            +Affect(row-cnt:1) cost in 11 ms.
             

            Replay record

            -

            Since Arthas stores the context of the call, you can even replay the method calling afterwards with extra option -p to replay the issue for advanced troubleshooting.

            -
            $ tt -i 1004 -p
            - RE-INDEX       1004
            - GMT-REPLAY     2018-12-04 11:26:00
            +

            Since Arthas stores the context of the call, you can even replay the method calling afterwards with extra option -p to replay the issue for advanced troubleshooting.

            +
            $ tt -i 1004 -p
            + RE-INDEX       1004
            + GMT-REPLAY     2018-12-04 11:26:00
              OBJECT         0x4b67cf4d
              CLASS          demo.MathGame
              METHOD         primeFactors
            - PARAMETERS[0]  @Integer[946738738]
            - IS-RETURN      true
            - IS-EXCEPTION   false
            - RETURN-OBJ     @ArrayList[
            -                    @Integer[2],
            -                    @Integer[11],
            -                    @Integer[17],
            -                    @Integer[2531387],
            -                ]
            -Time fragment[1004] successfully replayed.
            -Affect(row-cnt:1) cost in 14 ms.
            + PARAMETERS[0]  @Integer[946738738]
            + IS-RETURN      true
            + IS-EXCEPTION   false
            + RETURN-OBJ     @ArrayList[
            +                    @Integer[2],
            +                    @Integer[11],
            +                    @Integer[17],
            +                    @Integer[2531387],
            +                ]
            +Time fragment[1004] successfully replayed.
            +Affect(row-cnt:1) cost in 14 ms.
             

            F.Y.I

              -
            1. Loss of the ThreadLocal

              -

              Arthas save params into an array, then invoke the method with the params again. The method execute in another thead, so the ThreadLocal lost.

              +
            2. Loss of the ThreadLocal

              +

              Arthas save params into an array, then invoke the method with the params again. The method execute in another thead, so the ThreadLocal lost.

            3. params may be modified

              Arthas save params into an array, they are object references. The Objects may be modified by other code.

              @@ -461,6 +462,15 @@ Affect(row-cnt:1) cost in + + + + + @@ -116,12 +117,12 @@
            4. Usage @@ -210,11 +211,11 @@

              watch

              -

              Monitor methods in data aspect including return values, exceptions and parameters.

              +

              Monitor methods in data aspect including return values, exceptions and parameters.

              With the help of OGNL, you can easily check the details of variables when methods being invoked.

              Parameters & Options

              -

              There are four different scenarios for watch command, which makes it rather complicated.

              +

              There are four different scenarios for watch command, which makes it rather complicated.

              @@ -266,11 +267,11 @@

              F.Y.I

                -
              1. any valid OGNL expression as "{params,returnObj}" supported
              2. -
              3. there are four watching points: -b, -e, -s and -f (the first three are off in default while -f on);
              4. +
              5. any valid OGNL expression as "{params,returnObj}" supported
              6. +
              7. there are four watching points: -b, -e, -s and -f (the first three are off in default while -f on);
              8. at the watching point, Arthas will use the expression to evaluate the variables and print them out;
              9. -
              10. in parameters and out parameters are different since they can be modified within the invoked methods; params stands for in parameters in -bwhile out parameters in other watching points;
              11. -
              12. there are no return values and exceptions when using -b.
              13. +
              14. in parameters and out parameters are different since they can be modified within the invoked methods; params stands for in parameters in -bwhile out parameters in other watching points;
              15. +
              16. there are no return values and exceptions when using -b.

              Advanced:

              @@ -285,198 +286,198 @@

              Usage

              Start Demo

              -

              Start arthas-demo in Quick Start.

              +

              Start arthas-demo in Quick Start.

              -

              Check the out parameters and return value

              -
              $ watch demo.MathGame primeFactors "{params,returnObj}" -x 2
              +

              Check the out parameters and return value

              +
              $ watch demo.MathGame primeFactors "{params,returnObj}" -x 2
               Press Ctrl+C to abort.
              -Affect(class-cnt:1 , method-cnt:1) cost in 44 ms.
              -ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[
              -    @Object[][
              -        @Integer[535629513],
              -    ],
              -    @ArrayList[
              -        @Integer[3],
              -        @Integer[19],
              -        @Integer[191],
              -        @Integer[49199],
              -    ],
              -]
              +Affect(class-cnt:1 , method-cnt:1) cost in 44 ms.
              +ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[
              +    @Object[][
              +        @Integer[535629513],
              +    ],
              +    @ArrayList[
              +        @Integer[3],
              +        @Integer[19],
              +        @Integer[191],
              +        @Integer[49199],
              +    ],
              +]
               
              -

              Check in parameters

              -
              $ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b
              +

              Check in parameters

              +
              $ 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],
              -    ],
              +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,
              -]
              +]
               

              Compared to the previous check:

                -
              • return value is null since it’s -b.
              • +
              • return value is null since it’s -b.

              Check before and after at the same time

              -
              $ watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2
              +
              $ 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[1544665400],
              -    ],
              -    @MathGame[
              -        random=@Random[java.util.Random@522b408a],
              -        illegalArgumentCount=@Integer[13038],
              -    ],
              +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[1544665400],
              +    ],
              +    @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[1544665400],
              -    ],
              -    @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],
              -    ],
              -]
              +]
              +ts=2018-12-03 19:29:54; [cost=4.277392ms] result=@ArrayList[
              +    @Object[][
              +        @Integer[1544665400],
              +    ],
              +    @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],
              +    ],
              +]
               

              F.Y.I

                -
              • -n 2: threshold of execution times is 2.
              • +
              • -n 2: threshold of execution times is 2.
              • the first block of output is the before watching point;
              • -
              • *the order of the output determined by the watching order itself (nothing to do with the order of the options -b -s).
              • +
              • *the order of the output determined by the watching order itself (nothing to do with the order of the options -b -s).
              -

              Use -x to check more details

              -
              $ watch demo.MathGame primeFactors "{params,target}" -x 3
              +

              Use -x to check more details

              +
              $ watch demo.MathGame primeFactors "{params,target}" -x 3
               Press Ctrl+C to abort.
              -Affect(class-cnt:1 , method-cnt:1) cost in 58 ms.
              -ts=2018-12-03 19:34:19; [cost=0.587833ms] result=@ArrayList[
              -    @Object[][
              -        @Integer[47816758],
              -    ],
              -    @MathGame[
              -        random=@Random[
              -            serialVersionUID=@Long[3905348978240129619],
              -            seed=@AtomicLong[3133719055989],
              -            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@2eaa1027],
              -            seedOffset=@Long[24],
              -        ],
              -        illegalArgumentCount=@Integer[13159],
              -    ],
              -]
              +Affect(class-cnt:1 , method-cnt:1) cost in 58 ms.
              +ts=2018-12-03 19:34:19; [cost=0.587833ms] result=@ArrayList[
              +    @Object[][
              +        @Integer[47816758],
              +    ],
              +    @MathGame[
              +        random=@Random[
              +            serialVersionUID=@Long[3905348978240129619],
              +            seed=@AtomicLong[3133719055989],
              +            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@2eaa1027],
              +            seedOffset=@Long[24],
              +        ],
              +        illegalArgumentCount=@Integer[13159],
              +    ],
              +]
               
                -
              • -x: Expand level of object (1 by default)
              • +
              • -x: Expand level of object (1 by default)

              Use condition expressions to locate specific call

              -
              $ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"
              +
              $ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"
               Press Ctrl+C to abort.
              -Affect(class-cnt:1 , method-cnt:1) cost in 68 ms.
              -ts=2018-12-03 19:36:04; [cost=0.530255ms] result=@ArrayList[
              -    @Integer[-18178089],
              -    @MathGame[demo.MathGame@41cf53f9],
              -]
              +Affect(class-cnt:1 , method-cnt:1) cost in 68 ms.
              +ts=2018-12-03 19:36:04; [cost=0.530255ms] result=@ArrayList[
              +    @Integer[-18178089],
              +    @MathGame[demo.MathGame@41cf53f9],
              +]
               
              -

              Check exceptions

              -
              $ watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2
              +

              Check exceptions

              +
              $ watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2
               Press Ctrl+C to abort.
              -Affect(class-cnt:1 , method-cnt:1) cost in 62 ms.
              -ts=2018-12-03 19:38:00; [cost=1.414993ms] result=@ArrayList[
              -    @Integer[-1120397038],
              -    java.lang.IllegalArgumentException: number is: -1120397038, need >= 2
              -    at demo.MathGame.primeFactors(MathGame.java:46)
              -    at demo.MathGame.run(MathGame.java:24)
              -    at demo.MathGame.main(MathGame.java:16)
              +Affect(class-cnt:1 , method-cnt:1) cost in 62 ms.
              +ts=2018-12-03 19:38:00; [cost=1.414993ms] result=@ArrayList[
              +    @Integer[-1120397038],
              +    java.lang.IllegalArgumentException: number is: -1120397038, need >= 2
              +    at demo.MathGame.primeFactors(MathGame.java:46)
              +    at demo.MathGame.run(MathGame.java:24)
              +    at demo.MathGame.main(MathGame.java:16)
               ,
              -]
              +]
               
                -
              • -e: Trigger when an exception is thrown
              • -
              • throwExp: the exception object
              • +
              • -e: Trigger when an exception is thrown
              • +
              • throwExp: the exception object

              Filter by time cost

              -
              $ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2
              +
              $ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2
               Press Ctrl+C to abort.
              -Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
              -ts=2018-12-03 19:40:28; [cost=2112.168897ms] result=@ArrayList[
              -    @Object[][
              -        @Integer[2141897465],
              -    ],
              -    @ArrayList[
              -        @Integer[5],
              -        @Integer[428379493],
              -    ],
              -]
              +Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
              +ts=2018-12-03 19:40:28; [cost=2112.168897ms] result=@ArrayList[
              +    @Object[][
              +        @Integer[2141897465],
              +    ],
              +    @ArrayList[
              +        @Integer[5],
              +        @Integer[428379493],
              +    ],
              +]
               
                -
              • #cost>200 (ms) filter out all invokings that take less than 200ms.
              • +
              • #cost>200 (ms) filter out all invokings that take less than 200ms.

              Check the field of the target object

                -
              • target is the this object in java.
              • +
              • target is the this object in java.
              -
              $ watch demo.MathGame primeFactors 'target'
              +
              $ watch demo.MathGame primeFactors 'target'
               Press Ctrl+C to abort.
              -Affect(class-cnt:1 , method-cnt:1) cost in 52 ms.
              -ts=2018-12-03 19:41:52; [cost=0.477882ms] result=@MathGame[
              -    random=@Random[java.util.Random@522b408a],
              -    illegalArgumentCount=@Integer[13355],
              -]
              +Affect(class-cnt:1 , method-cnt:1) cost in 52 ms.
              +ts=2018-12-03 19:41:52; [cost=0.477882ms] result=@MathGame[
              +    random=@Random[java.util.Random@522b408a],
              +    illegalArgumentCount=@Integer[13355],
              +]
               
                -
              • target.field_name: the field of the current object.
              • +
              • target.field_name: the field of the current object.
              -
              $ watch demo.MathGame primeFactors 'target.illegalArgumentCount'
              +
              $ watch demo.MathGame primeFactors 'target.illegalArgumentCount'
               Press Ctrl+C to abort.
              -Affect(class-cnt:1 , method-cnt:1) cost in 67 ms.
              -ts=2018-12-03 20:04:34; [cost=131.303498ms] result=@Integer[8]
              -ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8]
              +Affect(class-cnt:1 , method-cnt:1) cost in 67 ms.
              +ts=2018-12-03 20:04:34; [cost=131.303498ms] result=@Integer[8]
              +ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8]
               
              @@ -555,6 +556,15 @@ Affect(class-cnt:1 , method-cnt:1) + + + + + @@ -260,6 +261,15 @@ + + + + + @@ -94,7 +95,7 @@
            5. 进阶使用
            6. 命令列表
            7. 用户案例
            8. -
            9. Questions and answers
            10. +
            11. 常见问题
            12. Fork me at GitHub
            13. 参与贡献
            14. Release Notes
            15. @@ -236,6 +237,15 @@ + + + + + @@ -117,7 +118,7 @@
        • 用户案例
        • -
        • Questions and answers
        • +
        • 常见问题
        • Fork me at GitHub
        • 参与贡献
        • Release Notes
        • @@ -195,26 +196,26 @@
          • 推荐直接使用ognl命令,更加灵活。
          -

          通过getstatic命令可以方便的查看类的静态属性。使用方法为getstatic class_name field_name

          -
          $ getstatic demo.MathGame random
          +

          通过getstatic命令可以方便的查看类的静态属性。使用方法为getstatic class_name field_name

          +
          $ getstatic demo.MathGame random
           field: random
          -@Random[
          -    serialVersionUID=@Long[3905348978240129619],
          -    seed=@AtomicLong[120955813885284],
          -    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@2eaa1027],
          -    seedOffset=@Long[24],
          -]
          +@Random[
          +    serialVersionUID=@Long[3905348978240129619],
          +    seed=@AtomicLong[120955813885284],
          +    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@2eaa1027],
          +    seedOffset=@Long[24],
          +]
           

          如果该静态属性是一个复杂对象,还可以支持在该属性上通过ognl表示进行遍历,过滤,访问对象的内部属性等操作。

          @@ -223,19 +224,18 @@ field: random
        • OGNL表达式官方指南:https://commons.apache.org/proper/commons-ognl/language-guide.html

        例如,假设n是一个Map,Map的Key是一个Enum,我们想过滤出Map中Key为某个Enum的值,可以写如下命令

        -
        $ getstatic com.alibaba.arthas.Test n 'entrySet().iterator.{? #this.key.name()=="STOP"}'
        +
        $ getstatic com.alibaba.arthas.Test n 'entrySet().iterator.{? #this.key.name()=="STOP"}'
         field: n
         @ArrayList[
             @Node[STOP=bbb],
         ]
         Affect(row-cnt:1) cost in 68 ms.
         
        -$ getstatic com.alibaba.arthas.Test m 'entrySet().iterator.{? #this.key=="a"}'
        +$ getstatic com.alibaba.arthas.Test m 'entrySet().iterator.{? #this.key=="a"}'
         field: m
         @ArrayList[
             @Node[a=aaa],
        -]
        -
        +]
        @@ -312,6 +312,15 @@ field: m + + + + + @@ -93,7 +94,7 @@
      • 进阶使用
      • 命令列表
      • 用户案例
      • -
      • Questions and answers
      • +
      • 常见问题
      • Fork me at GitHub
      • 参与贡献
      • Release Notes
      • @@ -206,152 +207,151 @@ 开启正则表达式匹配,默认为通配符匹配 -

        需要说明的是,第三个输入参数是脚本的绝对路径,比如 /tmp/test.groovy,不建议输入相对路径,比如 ./test.groovy

        +

        需要说明的是,第三个输入参数是脚本的绝对路径,比如 /tmp/test.groovy,不建议输入相对路径,比如 ./test.groovy

        五个关键函数声明

        -
        /**
        - * 增强脚本监听器
        - */
        -interface ScriptListener {
        +
        /**
        + * 增强脚本监听器
        + */
        +interface ScriptListener {
         
        -    /**
        -     * 脚本创建
        -     *
        -     * @param output 输出器
        -     */
        -    void create(Output output);
        +    /**
        +     * 脚本创建
        +     *
        +     * @param output 输出器
        +     */
        +    void create(Output output);
         
        -    /**
        -     * 脚本销毁
        -     *
        -     * @param output 输出器
        -     */
        -    void destroy(Output output);
        +    /**
        +     * 脚本销毁
        +     *
        +     * @param output 输出器
        +     */
        +    void destroy(Output output);
         
        -    /**
        -     * 方法执行前
        -     *
        -     * @param output 输出器
        -     * @param advice 通知点
        -     */
        -    void before(Output output, Advice advice);
        +    /**
        +     * 方法执行前
        +     *
        +     * @param output 输出器
        +     * @param advice 通知点
        +     */
        +    void before(Output output, Advice advice);
         
        -    /**
        -     * 方法正常返回
        -     *
        -     * @param output 输出器
        -     * @param advice 通知点
        -     */
        -    void afterReturning(Output output, Advice advice);
        +    /**
        +     * 方法正常返回
        +     *
        +     * @param output 输出器
        +     * @param advice 通知点
        +     */
        +    void afterReturning(Output output, Advice advice);
         
        -    /**
        -     * 方法异常返回
        -     *
        -     * @param output 输出器
        -     * @param advice 通知点
        -     */
        -    void afterThrowing(Output output, Advice advice);
        +    /**
        +     * 方法异常返回
        +     *
        +     * @param output 输出器
        +     * @param advice 通知点
        +     */
        +    void afterThrowing(Output output, Advice advice);
         
        -}
        +}
         
        -

        参数 Advice 说明

        -

        Advice 参数最主要是封装了通知节点的所有信息。参考表达式核心变量中关于该节点的描述。

        +

        参数 Advice 说明

        +

        Advice 参数最主要是封装了通知节点的所有信息。参考表达式核心变量中关于该节点的描述。

        -

        参数 Output 说明

        -

        Output 参数只拥有三个方法,主要的工作还是输出对应的文本信息

        -
        /**
        - * 输出器
        - */
        -interface Output {
        +

        参数 Output 说明

        +

        Output 参数只拥有三个方法,主要的工作还是输出对应的文本信息

        +
        /**
        + * 输出器
        + */
        +interface Output {
         
        -    /**
        -     * 输出字符串(不换行)
        -     *
        -     * @param string 待输出字符串
        -     * @return this
        -     */
        -    Output print(String string);
        +    /**
        +     * 输出字符串(不换行)
        +     *
        +     * @param string 待输出字符串
        +     * @return this
        +     */
        +    Output print(String string);
         
        -    /**
        -     * 输出字符串(换行)
        -     *
        -     * @param string 待输出字符串
        -     * @return this
        -     */
        -    Output println(String string);
        +    /**
        +     * 输出字符串(换行)
        +     *
        +     * @param string 待输出字符串
        +     * @return this
        +     */
        +    Output println(String string);
         
        -    /**
        -     * 结束当前脚本
        -     *
        -     * @return this
        -     */
        -    Output finish();
        +    /**
        +     * 结束当前脚本
        +     *
        +     * @return this
        +     */
        +    Output finish();
         
        -}
        +}
         

        一个输出日志的 groovy 脚本示例

        -
        import com.taobao.arthas.core.command.ScriptSupportCommand
        -import com.taobao.arthas.core.util.Advice
        +
        import com.taobao.arthas.core.command.ScriptSupportCommand
        +import com.taobao.arthas.core.util.Advice
         
        -import static java.lang.String.format
        +import static java.lang.String.format
         
        -/**
        - * 输出方法日志
        - */
        -public class Logger implements ScriptSupportCommand.ScriptListener {
        +/**
        + * 输出方法日志
        + */
        +public class Logger implements ScriptSupportCommand.ScriptListener {
         
        -    @Override
        -    void create(ScriptSupportCommand.Output output) {
        -        output.println("script create.");
        -    }
        +    @Override
        +    void create(ScriptSupportCommand.Output output) {
        +        output.println("script create.");
        +    }
         
        -    @Override
        -    void destroy(ScriptSupportCommand.Output output) {
        -        output.println("script destroy.");
        -    }
        +    @Override
        +    void destroy(ScriptSupportCommand.Output output) {
        +        output.println("script destroy.");
        +    }
         
        -    @Override
        -    void before(ScriptSupportCommand.Output output, Advice advice) {
        -        output.println(format("before:class=%s;method=%s;paramslen=%d;%s;",
        -                advice.getClazz().getSimpleName(),
        -                advice.getMethod().getName(),
        -                advice.getParams().length, advice.getParams()))
        -    }
        +    @Override
        +    void before(ScriptSupportCommand.Output output, Advice advice) {
        +        output.println(format("before:class=%s;method=%s;paramslen=%d;%s;",
        +                advice.getClazz().getSimpleName(),
        +                advice.getMethod().getName(),
        +                advice.getParams().length, advice.getParams()))
        +    }
         
        -    @Override
        -    void afterReturning(ScriptSupportCommand.Output output, Advice advice) {
        -        output.println(format("returning:class=%s;method=%s;",
        -                advice.getClazz().getSimpleName(),
        -                advice.getMethod().getName()))
        -    }
        +    @Override
        +    void afterReturning(ScriptSupportCommand.Output output, Advice advice) {
        +        output.println(format("returning:class=%s;method=%s;",
        +                advice.getClazz().getSimpleName(),
        +                advice.getMethod().getName()))
        +    }
         
        -    @Override
        -    void afterThrowing(ScriptSupportCommand.Output output, Advice advice) {
        -        output.println(format("throwing:class=%s;method=%s;",
        -                advice.getClazz().getSimpleName(),
        -                advice.getMethod().getName()))
        -    }
        -}
        +    @Override
        +    void afterThrowing(ScriptSupportCommand.Output output, Advice advice) {
        +        output.println(format("throwing:class=%s;method=%s;",
        +                advice.getClazz().getSimpleName(),
        +                advice.getMethod().getName()))
        +    }
        +}
         

        使用示例:

        -
        $ groovy com.alibaba.sample.petstore.dal.dao.ProductDao getProductById /Users/zhuyong/middleware/arthas/scripts/Logger.groovy -S
        +
        $ groovy com.alibaba.sample.petstore.dal.dao.ProductDao getProductById /Users/zhuyong/middleware/arthas/scripts/Logger.groovy -S
         script create.
         Press Ctrl+C to abort.
         Affect(class-cnt:1 , method-cnt:1) cost in 102 ms.
         before:class=IbatisProductDao;method=getProductById;paramslen=1;[Ljava.lang.Object;@45df64fc;
         returning:class=IbatisProductDao;method=getProductById;
         before:class=IbatisProductDao;method=getProductById;paramslen=1;[Ljava.lang.Object;@5b0e2d00;
        -returning:class=IbatisProductDao;method=getProductById;
        -
        +returning:class=IbatisProductDao;method=getProductById;
        @@ -420,6 +420,15 @@ returning:class=IbatisProductDao;method=getProductById; + + + + + @@ -94,7 +95,7 @@
      • 进阶使用
      • 命令列表
      • 用户案例
      • -
      • Questions and answers
      • +
      • 常见问题
      • Fork me at GitHub
      • 参与贡献
      • Release Notes
      • @@ -171,8 +172,8 @@

        Arthas(阿尔萨斯) 能为你做什么?

        arthas

        -

        Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。

        -

        当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

        +

        Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。

        +

        当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

        1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
        2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
        3. @@ -181,7 +182,7 @@
        4. 是否有一个全局视角来查看系统的运行状况?
        5. 有什么办法可以监控到JVM的实时运行状态?
        -

        Arthas支持JDK 6+,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

        +

        Arthas支持JDK 6+,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

        Contents

        @@ -193,7 +194,7 @@
      • 进阶使用
      • 命令列表
      • 用户案例
      • -
      • Questions and answers
      • +
      • 常见问题
      • Fork me at GitHub
      • 参与贡献
      • Release Notes
      • @@ -274,6 +275,15 @@ + + + + + @@ -92,8 +93,8 @@
      • English Docs
      • 安装
        • 快速安装
        • 全量安装
        • @@ -106,7 +107,7 @@
        • 进阶使用
        • 命令列表
        • 用户案例
        • -
        • Questions and answers
        • +
        • 常见问题
        • Fork me at GitHub
        • 参与贡献
        • Release Notes
        • @@ -182,42 +183,42 @@

          快速安装

          -

          使用arthas-boot(推荐)

          -

          下载arthas-boot.jar,然后用java -jar的方式启动:

          -
          $ wget https://alibaba.github.io/arthas/arthas-boot.jar
          +

          使用arthas-boot(推荐)

          +

          下载arthas-boot.jar,然后用java -jar的方式启动:

          +
          $ wget https://alibaba.github.io/arthas/arthas-boot.jar
           $ java -jar arthas-boot.jar
           

          打印帮助信息:

          -
          $ java -jar arthas-boot.jar -h
          +
          $ java -jar arthas-boot.jar -h
           
          • 如果下载速度比较慢,可以使用aliyun的镜像:

            -

            java -jar arthas-boot.jar --repo-mirror aliyun --use-http

            +

            java -jar arthas-boot.jar --repo-mirror aliyun --use-http

          -

          使用as.sh

          -

          Arthas 支持在 Linux/Unix/Mac 等平台上一键安装,请复制以下内容,并粘贴到命令行中,敲 回车 执行即可:

          -
          $ curl -L https://alibaba.github.io/arthas/install.sh | sh
          +

          使用as.sh

          +

          Arthas 支持在 Linux/Unix/Mac 等平台上一键安装,请复制以下内容,并粘贴到命令行中,敲 回车 执行即可:

          +
          $ curl -L https://alibaba.github.io/arthas/install.sh | sh
           
          -

          上述命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。

          -

          直接在shell下面执行./as.sh,就会进入交互界面。

          -

          也可以执行./as.sh -h来获取更多参数信息。

          +

          上述命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。

          +

          直接在shell下面执行./as.sh,就会进入交互界面。

          +

          也可以执行./as.sh -h来获取更多参数信息。

          全量安装

          最新版本,点击下载:Arthas

          -

          解压后,在文件夹里有arthas-boot.jar,直接用java -jar的方式启动:

          -
          $ java -jar arthas-boot.jar
          +

          解压后,在文件夹里有arthas-boot.jar,直接用java -jar的方式启动:

          +
          $ java -jar arthas-boot.jar
           

          打印帮助信息:

          -
          $ java -jar arthas-boot.jar -h
          +
          $ java -jar arthas-boot.jar -h
           
          @@ -234,11 +235,11 @@ $ java -jar arthas-boot.jar
          • 在 Linux/Unix/Mac 平台

            删除下面文件:

            -
            $ rm -rf ~/.arthas/
            +
            $ rm -rf ~/.arthas/
             
          • -
          • Windows平台直接删除user home下面的.arthas目录

            +
          • Windows平台直接删除user home下面的.arthas目录

          @@ -317,6 +318,15 @@ $ java -jar arthas-boot.jar + + + + + @@ -107,7 +108,7 @@
        • jad
        • 用户案例
        • -
        • Questions and answers
        • +
        • 常见问题
        • Fork me at GitHub
        • 参与贡献
        • Release Notes
        • @@ -203,7 +204,7 @@

          jad

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

          jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻辑;

          +

          jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻辑;

          • 在 Arthas Console 上,反编译出来的源码是带语法高亮的,阅读更方便
          • 当然,反编译出来的 java 代码可能会存在语法错误,但不影响你进行阅读理解
          • @@ -235,41 +236,41 @@

            使用参考

            -

            编绎java.lang.String

            -
            $ jad java.lang.String
            +

            编绎java.lang.String

            +
            $ jad java.lang.String
             
            -ClassLoader:
            +ClassLoader:
             
            -Location:
            +Location:
             
            -/*
            -* Decompiled with CFR 0_132.
            -*/
            -package java.lang;
            +/*
            +* Decompiled with CFR 0_132.
            +*/
            +package java.lang;
             
            -import java.io.ObjectStreamField;
            -...
            -public final class String
            -implements Serializable,
            -Comparable<String>,
            -CharSequence {
            -    private final char[] value;
            -    private int hash;
            -    private static final long serialVersionUID = -6849794470754667710L;
            -    private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
            -    public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
            +import java.io.ObjectStreamField;
            +...
            +public final class String
            +implements Serializable,
            +Comparable<String>,
            +CharSequence {
            +    private final char[] value;
            +    private int hash;
            +    private static final long serialVersionUID = -6849794470754667710L;
            +    private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
            +    public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
             
            -    public String(byte[] arrby, int n, int n2) {
            -        String.checkBounds(arrby, n, n2);
            -        this.value = StringCoding.decode(arrby, n, n2);
            -    }
            -...
            +    public String(byte[] arrby, int n, int n2) {
            +        String.checkBounds(arrby, n, n2);
            +        this.value = StringCoding.decode(arrby, n, n2);
            +    }
            +...
             

            反编绎指定的函数

            -
            $ jad demo.MathGame main
            +
            $ jad demo.MathGame main
             
             ClassLoader:
             +-sun.misc.Launcher$AppClassLoader@3d4eac69
            @@ -293,23 +294,23 @@ Affect(row-cnt:1) cost in 228 ms.
             

            反编绎时指定ClassLoader

            -
            当有多个 ClassLoader 都加载了这个类时,jad 命令会输出对应 ClassLoader 实例的 hashcode,然后你只需要重新执行 jad 命令,并使用参数 -c <hashcode> 就可以反编译指定 ClassLoader 加载的那个类了;
            -
            $ jad org.apache.log4j.Logger
            +
            当有多个 ClassLoader 都加载了这个类时,jad 命令会输出对应 ClassLoader 实例的 hashcode,然后你只需要重新执行 jad 命令,并使用参数 -c 就可以反编译指定 ClassLoader 加载的那个类了;
            +
            $ jad org.apache.log4j.Logger
             
             Found more than one class for: org.apache.log4j.Logger, Please use jad -c hashcode org.apache.log4j.Logger
             HASHCODE  CLASSLOADER
            -69dcaba4  +-monitor's ModuleClassLoader
            +69dcaba4  +-monitor's ModuleClassLoader
             6e51ad67  +-java.net.URLClassLoader@6e51ad67
                         +-sun.misc.Launcher$AppClassLoader@6951a712
                         +-sun.misc.Launcher$ExtClassLoader@6fafc4c2
            -2bdd9114  +-pandora-qos-service's ModuleClassLoader
            -4c0df5f8  +-pandora-framework's ModuleClassLoader
            +2bdd9114  +-pandora-qos-service's ModuleClassLoader
            +4c0df5f8  +-pandora-framework's ModuleClassLoader
             
             Affect(row-cnt:0) cost in 38 ms.
             $ jad org.apache.log4j.Logger -c 69dcaba4
             
             ClassLoader:
            -+-monitor's ModuleClassLoader
            ++-monitor's ModuleClassLoader
             
             Location:
             /Users/admin/app/log4j-1.2.14.jar
            @@ -409,6 +410,15 @@ Affect(row-cnt:1) cost in 190 ms.
             
             
             
            +
            +
            +
            +
             
            +
              
             
             
            @@ -122,7 +123,7 @@
             
        • 用户案例
        • -
        • Questions and answers
        • +
        • 常见问题
        • Fork me at GitHub
        • 参与贡献
        • Release Notes
        • @@ -201,7 +202,7 @@
          查看当前JVM信息

          使用参考

          -
          $ jvm
          +
          $ jvm
            CATEGORY            INFO
           ------------------------------------------------------------------------------------------------------------------------------------
           
          @@ -287,8 +288,7 @@
                                 MAX-FILE-DESCRIPTOR-COUNT  10240
                                 OPEN-FILE-DESCRIPTOR-COUNT 648
                                 
          -Affect cost in 2 ms.
          -
          +Affect cost in 2 ms.
          @@ -383,6 +383,15 @@ Affect cost in 2 ms. + + + + + @@ -93,7 +94,7 @@
        • 进阶使用
        • 命令列表
        • 用户案例
        • -
        • Questions and answers
        • +
        • 常见问题
        • Fork me at GitHub
        • 参与贡献
        • Release Notes
        • @@ -166,7 +167,7 @@

          Arthas 命令行快捷键

          -

          keymap命令输出当前的快捷键映射表:

          +

          keymap命令输出当前的快捷键映射表:

          默认的快捷键如下:

          @@ -294,35 +295,34 @@
            -
          • 任何时候 tab 键,会根据当前的输入给出提示
          • -
          • 命令后敲 - 或 -- ,然后按 tab 键,可以展示出此命令具体的选项
          • +
          • 任何时候 tab 键,会根据当前的输入给出提示
          • +
          • 命令后敲 - 或 -- ,然后按 tab 键,可以展示出此命令具体的选项

          自定义快捷键

          -

          在当前用户目录下新建$USER_HOME/.arthas/conf/inputrc文件,加入自定义配置。

          -

          假设我是vim的重度用户,我要把ctrl+h设置为光标向前一个字符,则设置如下,首先拷贝默认配置

          -
          "\C-a": beginning-of-line
          -"\C-e": end-of-line
          -"\C-f": forward-word
          -"\C-b": backward-word
          -"\e[D": backward-char
          -"\e[C": forward-char
          -"\e[B": next-history
          -"\e[A": previous-history
          -"\C-h": backward-delete-char
          -"\C-?": backward-delete-char
          -"\C-u": undo
          -"\C-d": delete-char
          -"\C-k": kill-line
          -"\C-i": complete
          -"\C-j": accept-line
          -"\C-m": accept-line
          -"\C-w": backward-delete-word
          -"\C-x\e[3~": backward-kill-line
          -"\e\C-?": backward-kill-word
          -
          +

          在当前用户目录下新建$USER_HOME/.arthas/conf/inputrc文件,加入自定义配置。

          +

          假设我是vim的重度用户,我要把ctrl+h设置为光标向前一个字符,则设置如下,首先拷贝默认配置

          +
          "\C-a": beginning-of-line
          +"\C-e": end-of-line
          +"\C-f": forward-word
          +"\C-b": backward-word
          +"\e[D": backward-char
          +"\e[C": forward-char
          +"\e[B": next-history
          +"\e[A": previous-history
          +"\C-h": backward-delete-char
          +"\C-?": backward-delete-char
          +"\C-u": undo
          +"\C-d": delete-char
          +"\C-k": kill-line
          +"\C-i": complete
          +"\C-j": accept-line
          +"\C-m": accept-line
          +"\C-w": backward-delete-word
          +"\C-x\e[3~": backward-kill-line
          +"\e\C-?": backward-kill-word
          -

          然后把"\C-h": backward-delete-char换成"\C-h": backward-char,然后重新连接即可。

          +

          然后把"\C-h": backward-delete-char换成"\C-h": backward-char,然后重新连接即可。

          后台异步命令相关快捷键

          @@ -399,6 +399,15 @@ + + + + + @@ -93,7 +94,7 @@
        • 进阶使用
        • 命令列表
        • 用户案例
        • -
        • Questions and answers
        • +
        • 常见问题
        • Fork me at GitHub
        • 参与贡献
        • Release Notes
        • @@ -171,30 +172,27 @@
          1. 下载最新版本

            最新版本,点击下载:Arthas

            -

            如果下载速度比较慢,可以尝试用阿里云的镜像仓库,比如要下载3.x.x版本(替换3.x.x为最新版本),下载的url是:

            +

            如果下载速度比较慢,可以尝试用阿里云的镜像仓库,比如要下载3.x.x版本(替换3.x.x为最新版本),下载的url是:

            https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/3.x.x/arthas-packaging-3.x.x-bin.zip

          2. 解压缩arthas的压缩包

            -
            unzip arthas-packaging-bin.zip
            -
            +
            unzip arthas-packaging-bin.zip
          3. 安装Arthas

            安装之前最好把所有老版本的Arthas全都删掉

            -
            sudo su admin
            -rm -rf /home/admin/.arthas/lib/*
            -cd arthas
            -./install-local.sh
            -
            +
            sudo su admin
            +rm -rf /home/admin/.arthas/lib/*
            +cd arthas
            +./install-local.sh

            注意,这里根据你需要诊断的Java进程的所属用户进行切换

          4. 启动Arthas

            -

            启动之前,请确保老版本的Arthas已经shutdown.

            -
            ./as.sh
            -
            +

            启动之前,请确保老版本的Arthas已经shutdown.

            +
            ./as.sh
          @@ -203,20 +201,19 @@

          以脚本的方式启动as.sh/as.bat

          Linux/Unix/Mac

          -

          Arthas 支持在 Linux/Unix/Mac 等平台上一键安装,请复制以下内容,并粘贴到命令行中,敲 回车 执行即可:

          -
          curl -L https://alibaba.github.io/arthas/install.sh | sh
          +

          Arthas 支持在 Linux/Unix/Mac 等平台上一键安装,请复制以下内容,并粘贴到命令行中,敲 回车 执行即可:

          +
          curl -L https://alibaba.github.io/arthas/install.sh | sh
           
          -

          上述命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。

          -

          直接在shell下面执行./as.sh,就会进入交互界面。

          -

          也可以执行./as.sh -h来获取更多参数信息。

          +

          上述命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。

          +

          直接在shell下面执行./as.sh,就会进入交互界面。

          +

          也可以执行./as.sh -h来获取更多参数信息。

          Windows

          最新版本,点击下载:Arthas

          -

          下载解压后在bin目录有 as.bat。此脚本暂时只接受一个参数 pid,即只能诊断本机上的 Java 进程。(欢迎精通bat脚本的开发者改进)

          -
          as.bat <pid>
          -
          +

          下载解压后在bin目录有 as.bat。此脚本暂时只接受一个参数 pid,即只能诊断本机上的 Java 进程。(欢迎精通bat脚本的开发者改进)

          +
          as.bat <pid>
          @@ -225,31 +222,31 @@

          如果启动遇到问题,可以尝试手动拼接出命令行参数来启动。

          1. 查找目录jvm的java文件路径。

            -

            在linux/mac上执行ps aux | grep java,在windows上可以通过进程管理器来查看。假设是/opt/jdk1.8/bin/java。

            +

            在linux/mac上执行ps aux | grep java,在windows上可以通过进程管理器来查看。假设是/opt/jdk1.8/bin/java。

          2. 拼接出命令行

            -
            /opt/jdk1.8/bin/java -Xbootclasspath/a:/opt/jdk1.8/lib/tools.jar \
            - -jar /tmp/arthas-packaging/arthas-core.jar \
            - -pid 15146 \
            - -target-ip 127.0.0.1 -telnet-port 3658 -http-port 8563 \
            - -core /tmp/arthas-packaging/arthas-core.jar \
            +
            /opt/jdk1.8/bin/java -Xbootclasspath/a:/opt/jdk1.8/lib/tools.jar \
            + -jar /tmp/arthas-packaging/arthas-core.jar \
            + -pid 15146 \
            + -target-ip 127.0.0.1 -telnet-port 3658 -http-port 8563 \
            + -core /tmp/arthas-packaging/arthas-core.jar \
              -agent /tmp/arthas-packaging/arthas/arthas-agent.jar
             

            命令行分几部分组成:

              -
            • -Xbootclasspath 增加tools.jar
            • -
            • -jar /tmp/arthas-packaging/arthas-core.jar 指定main函数入口
            • -
            • -pid 15146 指定目标java进程ID
            • -
            • -target-ip 127.0.0.1 指定IP
            • -
            • -telnet-port 3658 -http-port 8563 指定telnet和http端口
            • -
            • -core /tmp/arthas-packaging/arthas-core.jar -agent /tmp/arthas-packaging/arthas/arthas-agent.jar 指定core/agent jar包
            • +
            • -Xbootclasspath 增加tools.jar
            • +
            • -jar /tmp/arthas-packaging/arthas-core.jar 指定main函数入口
            • +
            • -pid 15146 指定目标java进程ID
            • +
            • -target-ip 127.0.0.1 指定IP
            • +
            • -telnet-port 3658 -http-port 8563 指定telnet和http端口
            • +
            • -core /tmp/arthas-packaging/arthas-core.jar -agent /tmp/arthas-packaging/arthas/arthas-agent.jar 指定core/agent jar包
            -

            如果是jdk > 9,即9/10/11以上的版本,不需要指定tools.jar,直接去掉-Xbootclasspath 的配置即可。

            -

            启动目志输出在~/logs/arthas/arthas.log里。

            +

            如果是jdk > 9,即9/10/11以上的版本,不需要指定tools.jar,直接去掉-Xbootclasspath 的配置即可。

            +

            启动目志输出在~/logs/arthas/arthas.log里。

          3. attach成功之后,使用telnet连接

            -
            telnet 127.0.0.1 3658
            +
            telnet 127.0.0.1 3658
             
          4. @@ -321,6 +318,15 @@ + + + + + @@ -122,7 +123,7 @@
      • 用户案例
      • -
      • Questions and answers
      • +
      • 常见问题
      • Fork me at GitHub
      • 参与贡献
      • Release Notes
      • @@ -199,9 +200,9 @@

        monitor

        方法执行监控
        -

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

        -

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

        -

        实时返回命令是输入之后立即返回,而非实时返回的命令,则是不断的等待目标 Java 进程返回信息,直到用户输入 Ctrl+C 为止。

        +

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

        +

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

        +

        实时返回命令是输入之后立即返回,而非实时返回的命令,则是不断的等待目标 Java 进程返回信息,直到用户输入 Ctrl+C 为止。

        服务端是以任务的形式在后台跑任务,植入的代码随着任务的中止而不会被执行,所以任务关闭后,不会对原有性能产生太大影响,而且原则上,任何Arthas命令不会引起原有业务逻辑的改变。

        监控的维度说明

        @@ -249,7 +250,7 @@

        参数说明

        -

        方法拥有一个命名参数 [c:],意思是统计周期(cycle of output),拥有一个整型的参数值

        +

        方法拥有一个命名参数 [c:],意思是统计周期(cycle of output),拥有一个整型的参数值

        @@ -278,32 +279,32 @@

        使用参考

        -
        $ monitor -c 5 demo.MathGame primeFactors
        +
        $ monitor -c 5 demo.MathGame primeFactors
         Press Ctrl+C to abort.
        -Affect(class-cnt:1 , method-cnt:1) cost in 94 ms.
        - timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
        +Affect(class-cnt:1 , method-cnt:1) cost in 94 ms.
        + timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
         -----------------------------------------------------------------------------------------------
        - 2018-12-03 19:06:38  demo.MathGame  primeFactors  5      1        4     1.15        80.00%
        + 2018-12-03 19:06:38  demo.MathGame  primeFactors  5      1        4     1.15        80.00%
         
        - timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
        + timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
         -----------------------------------------------------------------------------------------------
        - 2018-12-03 19:06:43  demo.MathGame  primeFactors  5      3        2     42.29       40.00%
        + 2018-12-03 19:06:43  demo.MathGame  primeFactors  5      3        2     42.29       40.00%
         
        - timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
        + timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
         -----------------------------------------------------------------------------------------------
        - 2018-12-03 19:06:48  demo.MathGame  primeFactors  5      3        2     67.92       40.00%
        + 2018-12-03 19:06:48  demo.MathGame  primeFactors  5      3        2     67.92       40.00%
         
        - timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
        + timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
         -----------------------------------------------------------------------------------------------
        - 2018-12-03 19:06:53  demo.MathGame  primeFactors  5      2        3     0.25        60.00%
        + 2018-12-03 19:06:53  demo.MathGame  primeFactors  5      2        3     0.25        60.00%
         
        - timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
        + timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
         -----------------------------------------------------------------------------------------------
        - 2018-12-03 19:06:58  demo.MathGame  primeFactors  1      1        0     0.45        0.00%
        + 2018-12-03 19:06:58  demo.MathGame  primeFactors  1      1        0     0.45        0.00%
         
        - timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
        + timestamp            class          method        total  success  fail  avg-rt(ms)  fail-rate
         -----------------------------------------------------------------------------------------------
        - 2018-12-03 19:07:03  demo.MathGame  primeFactors  2      2        0     3182.72     0.00%
        + 2018-12-03 19:07:03  demo.MathGame  primeFactors  2      2        0     3182.72     0.00%
         
        @@ -382,6 +383,15 @@ Affect(class-cnt:1 , method-cnt:1) + + + + + @@ -121,7 +122,7 @@
    • 用户案例
    • -
    • Questions and answers
    • +
    • 常见问题
    • Fork me at GitHub
    • 参与贡献
    • Release Notes
    • @@ -230,37 +231,37 @@
    • OGNL表达式官方指南:https://commons.apache.org/proper/commons-ognl/language-guide.html

    调用静态函数:

    -
    $ ognl '@java.lang.System@out.println("hello")'
    +
    $ ognl '@java.lang.System@out.println("hello")'
     null
     

    获取静态类的静态字段:

    -
    $ 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],
    -]
    +
    $ 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],
    +]
     

    执行多行表达式,赋值给临时变量,返回一个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],
    -]
    +
    $ 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],
    +]
     
    @@ -339,6 +340,15 @@ null + + + + + @@ -120,7 +121,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -250,11 +251,10 @@

    使用说明

    例如,想打开执行结果存日志功能,输入如下命令即可:

    -
    $ options save-result true                                                                                         
    +
    $ options save-result true                                                                                         
      NAME         BEFORE-VALUE  AFTER-VALUE                                                                            
     ----------------------------------------                                                                           
    - save-result  false         true
    -
    + save-result false true
    @@ -332,6 +332,15 @@ + + + + + @@ -95,7 +96,7 @@
  • 1. 启动Demo
  • 2. 启动arthas
  • 3. 查看dashboard
  • -
  • 4. 通过thread命令来获取到arthas-demo进程的Main Class
  • +
  • 4. 通过thread命令来获取到arthas-demo进程的Main Class
  • 5. 通过jad来反编绎Main Class
  • 6. watch
  • 5. 退出arthas
  • @@ -104,7 +105,7 @@
  • 进阶使用
  • 命令列表
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -179,41 +180,41 @@

    快速入门

    1. 启动Demo

    -
    $ wget https://alibaba.github.io/arthas/arthas-demo.jar
    +
    $ wget https://alibaba.github.io/arthas/arthas-demo.jar
     $ java -jar arthas-demo.jar
     
    -

    arthas-demo是一个简单的程序,每隔一秒生成一个随机数,再执行质因式分解,并打印出分解结果。

    -

    arthas-demo源代码:查看

    +

    arthas-demo是一个简单的程序,每隔一秒生成一个随机数,再执行质因式分解,并打印出分解结果。

    +

    arthas-demo源代码:查看

    2. 启动arthas

    在命令行下面执行:

    -
    $ wget https://alibaba.github.io/arthas/arthas-boot.jar
    +
    $ wget https://alibaba.github.io/arthas/arthas-boot.jar
     $ java -jar arthas-boot.jar
     
      -
    • 执行该程序的用户需要和目标进程具有相同的权限。比如以admin用户来执行:sudo su admin && java -jar arthas-boot.jar 或 sudo -u admin -EH java -jar arthas-boot.jar。
    • -
    • 如果attatch不上目标进程,可以查看~/logs/arthas/ 目录下的日志。
    • -
    • 如果下载速度比较慢,可以使用aliyun的镜像:java -jar arthas-boot.jar --repo-mirror aliyun --use-http
    • -
    • java -jar arthas-boot.jar -h 打印更多参数信息。
    • +
    • 执行该程序的用户需要和目标进程具有相同的权限。比如以admin用户来执行:sudo su admin && java -jar arthas-boot.jar 或 sudo -u admin -EH java -jar arthas-boot.jar。
    • +
    • 如果attatch不上目标进程,可以查看~/logs/arthas/ 目录下的日志。
    • +
    • 如果下载速度比较慢,可以使用aliyun的镜像:java -jar arthas-boot.jar --repo-mirror aliyun --use-http
    • +
    • java -jar arthas-boot.jar -h 打印更多参数信息。

    选择应用java进程:

    -
    $ $ java -jar arthas-boot.jar
    +
    $ $ java -jar arthas-boot.jar
     * [1]: 35542
       [2]: 71560 arthas-demo.jar
     

    Demo进程是第2个,则输入2,再输入回车/enter。Arthas会attach到目标进程上,并输出日志:

    -
    [INFO] Try to attach process 71560
    +
    [INFO] Try to attach process 71560
     [INFO] Attach process 71560 success.
     [INFO] arthas-client connect 127.0.0.1 3658
       ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
    - /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
    -|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
    -|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
    -`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
    + /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
    +|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
    +|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
    +`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
     
     wiki: https://alibaba.github.io/arthas
     version: 3.0.5.20181127201536
    @@ -226,8 +227,8 @@ $
     

    3. 查看dashboard

    -

    输入dashboard,按enter/回车,会展示当前进程的信息,按ctrl+c可以中断执行。

    -
    $ dashboard
    +

    输入dashboard,按enter/回车,会展示当前进程的信息,按ctrl+c可以中断执行。

    +
    $ dashboard
     ID     NAME                   GROUP          PRIORI STATE  %CPU    TIME   INTERRU DAEMON
     17     pool-2-thread-1        system         5      WAITIN 67      0:0    false   false
     27     Timer-for-arthas-dashb system         10     RUNNAB 32      0:0    false   true
    @@ -262,15 +263,15 @@ java.home              /Library/Java/JavaVir
     
    -

    4. 通过thread命令来获取到arthas-demo进程的Main Class

    -
    $ thread -n -1 | grep 'main('
    -    at demo.MathGame.main(MathGame.java:17)
    +

    4. 通过thread命令来获取到arthas-demo进程的Main Class

    +
    $ thread -n -1 | grep 'main('
    +    at demo.MathGame.main(MathGame.java:17)
     

    5. 通过jad来反编绎Main Class

    -
    $ jad demo.MathGame
    +
    $ jad demo.MathGame
     
     ClassLoader:
     +-sun.misc.Launcher$AppClassLoader@3d4eac69
    @@ -319,9 +320,9 @@ public class MathGame {
             Iterator<Integer> iterator = primeFactors.iterator();
             while (iterator.hasNext()) {
                 int factor = iterator.next();
    -            sb.append(factor).append('*');
    +            sb.append(factor).append('*');
             }
    -        if (sb.charAt(sb.length() - 1) == '*') {
    +        if (sb.charAt(sb.length() - 1) == '*') {
                 sb.deleteCharAt(sb.length() - 1);
             }
             System.out.println(sb);
    @@ -353,8 +354,8 @@ Affect(row-cnt:1) cost in 970 ms.
     

    6. watch

    -

    通过watch命令来查看demo.MathGame#primeFactors函数的返回值:

    -
    $ watch demo.MathGame primeFactors returnObj
    +

    通过watch命令来查看demo.MathGame#primeFactors函数的返回值:

    +
    $ watch demo.MathGame primeFactors returnObj
     Press Ctrl+C to abort.
     Affect(class-cnt:1 , method-cnt:1) cost in 107 ms.
     ts=2018-11-28 19:22:30; [cost=1.715367ms] result=null
    @@ -390,8 +391,8 @@ ts=2018-11-28 19:22:35; [cost=29.969732ms] result=@ArrayList[
     

    5. 退出arthas

    -

    如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。

    -

    如果想完全退出arthas,可以执行shutdown命令。

    +

    如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。

    +

    如果想完全退出arthas,可以执行shutdown命令。

    @@ -468,6 +469,15 @@ ts=2018-11-28 19:22:35; [cost=29.969732ms] result=@ArrayList[ + + + + + @@ -121,7 +122,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -197,7 +198,7 @@

    redefine

    -
    加载外部的.class文件,redefine jvm已加载的类。
    +
    加载外部的.class文件,redefine jvm已加载的类。

    参考:Instrumentation#redefineClasses

    注意, redefine后的原来的类不能恢复,redefine有可能失败(比如增加了新的field),参考jdk本身的文档。
    @@ -223,9 +224,8 @@

    使用参考

    -
       redefine -p /tmp/Test.class
    -   redefine -c 327a647b -p /tmp/Test.class /tmp/Test\$Inner.class
    -
    +
       redefine -p /tmp/Test.class
    +   redefine -c 327a647b -p /tmp/Test.class /tmp/Test\$Inner.class
    @@ -303,6 +303,15 @@ + + + + + @@ -95,7 +96,7 @@
  • 进阶使用
  • 命令列表
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
      @@ -258,12 +259,12 @@
    • [#123] 修复反复attach/shutdown造成classloader泄露的问题
    • 优化命令中的帮助提示信息
    • [#126] 修复tm命令文档链接错乱的问题
    • -
    • [#122] classloader命令中过滤掉sun.reflect.DelegatingClassLoader
    • +
    • [#122] classloader命令中过滤掉sun.reflect.DelegatingClassLoader
    • [#129] 修复classloader层次展示的问题
    • [#125] arthas输出的log不主动换行,对于日志解析更加友好
    • [#96] sc等命令支持com/taobao/xxx/TestClass这样的格式,以后复制粘贴不需要在把’/’替换成’.’啦
    • [#124] 修复某些情况下trace的时间为负值的问题
    • -
    • [#128] tt命令的结果默认自动展开,不需要再增加-x 2来看到参数,异常的详细信息了。
    • +
    • [#128] tt命令的结果默认自动展开,不需要再增加-x 2来看到参数,异常的详细信息了。
    • [#130] 修复当端口冲突时,没有很好地打印错误,而是进入了一个出错的交互界面的问题
    • [#98] 修复Arthas启动时,如果下载更新失败,导致启动失败的问题
    • [#139] 修复某些特殊情况下agent attach失败的问题
    • @@ -324,7 +325,7 @@

      v2016-01-18

        -
      • 优化 jad,实时 dump 内存 byte array,并使用 jd-core-java 反编译,支持行号显示
      • +
      • 优化 jad,实时 dump 内存 byte array,并使用 jd-core-java 反编译,支持行号显示
      • 修复 tt 命令在监控与线程上下文相关的方法调用时,显示/重做等场景下的 bug
      @@ -422,6 +423,15 @@ + + + + + @@ -93,7 +94,7 @@
    • 进阶使用
    • 命令列表
    • 用户案例
    • -
    • Questions and answers
    • +
    • 常见问题
    • Fork me at GitHub
    • 参与贡献
    • Release Notes
    • @@ -167,10 +168,10 @@

      reset命令

      -
      重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端shutdown时会重置所有增强过的类
      +
      重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端shutdown时会重置所有增强过的类

      使用参考

      -
      $ reset -h
      +
      $ reset -h
        USAGE:
          reset [-h] [-E] [class-pattern]
       
      @@ -185,13 +186,12 @@
        OPTIONS:
        -h, --help                                                         this help
        -E, --regex                                                        Enable regular expression to match (wildcard matching by default)
      - <class-pattern>                                                    Path and classname of Pattern Matching
      -
      + <class-pattern> Path and classname of Pattern Matching

      还原指定类

      -
      $ trace Test test
      +
      $ trace Test test
       Press Ctrl+C to abort.
       Affect(class-cnt:1 , method-cnt:1) cost in 57 ms.
       `---ts=2017-10-26 17:10:33;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@14dad5dc
      @@ -201,21 +201,19 @@ Affect(class-cnt:1 , method-cnt:1) cost in 57 ms.
           `---[0.068692ms] Test:test()
       
       $ reset Test
      -Affect(class-cnt:1 , method-cnt:0) cost in 11 ms.
      -
      +Affect(class-cnt:1 , method-cnt:0) cost in 11 ms.

      还原所有类

      -
      $ trace Test test
      +
      $ trace Test test
       Press Ctrl+C to abort.
       Affect(class-cnt:1 , method-cnt:1) cost in 15 ms.
       `---ts=2017-10-26 17:12:06;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@14dad5dc
           `---[0.128518ms] Test:test()
       
       $ reset
      -Affect(class-cnt:1 , method-cnt:0) cost in 9 ms.
      -
      +Affect(class-cnt:1 , method-cnt:0) cost in 9 ms.
      @@ -284,6 +282,15 @@ Affect(class-cnt:1 , method-cnt:0) cost in 9 ms. + + + + + @@ -115,7 +116,7 @@
    • 命令列表
    • 用户案例
    • -
    • Questions and answers
    • +
    • 常见问题
    • Fork me at GitHub
    • 参与贡献
    • Release Notes
    • @@ -195,29 +196,29 @@
      • 默认情况下,该功能是关闭的,如果需要开启,请执行以下命令:
      -
      $ options save-result true
      +
      $ options save-result true
        NAME         BEFORE-VALUE  AFTER-VALUE
       ----------------------------------------
      - save-result  false         true
      -Affect(row-cnt:1) cost in 3 ms.
      + save-result  false         true
      +Affect(row-cnt:1) cost in 3 ms.
       

      看到上面的输出,即表示成功开启该功能;

      • 日志文件路径
      -

      结果会异步保存在:{user.home}/logs/arthas-cache/result.log,请定期进行清理,以免占据磁盘空间

      +

      结果会异步保存在:{user.home}/logs/arthas-cache/result.log,请定期进行清理,以免占据磁盘空间

      使用新版本Arthas的异步后台任务将结果存日志文件

      -
      $ trace Test t >>  &
      -job id  : 2
      +
      $ trace Test t >>  &
      +job id  : 2
       cache location  : /Users/admin/logs/arthas-cache/28198/2
       

      此时命令会在后台异步执行,并将结果异步保存在文件(~/logs/arthas-cache/${PID}/${JobId})中;

        -
      • 此时任务的执行不受session断开的影响;任务默认超时时间是1天,可以通过全局 options 命令修改默认超时时间;
      • -
      • 此命令的结果将异步输出到文件中;此时不管 save-result 是否为true,都不会再往~/logs/arthas-cache/result.log 中异步写结果
      • +
      • 此时任务的执行不受session断开的影响;任务默认超时时间是1天,可以通过全局 options 命令修改默认超时时间;
      • +
      • 此命令的结果将异步输出到文件中;此时不管 save-result 是否为true,都不会再往~/logs/arthas-cache/result.log 中异步写结果
      @@ -295,6 +296,15 @@ cache location : /Users/admin/logs/arthas-cache/28198/2 + + + + + @@ -124,7 +125,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -201,7 +202,7 @@

    sc

    查看JVM已加载的类信息
    -

    “Search-Class” 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息,这个命令支持的参数有 [d]、[E]、[f] 和 [x:]。

    +

    “Search-Class” 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息,这个命令支持的参数有 [d]、[E]、[f] 和 [x:]。

    参数说明

    @@ -240,80 +241,80 @@
    -
    class-pattern支持全限定名,如com.taobao.test.AAA,也支持com/taobao/test/AAA这样的格式,这样,我们从异常堆栈里面把类名拷贝过来的时候,不需要在手动把/替换为.啦。
    +
    class-pattern支持全限定名,如com.taobao.test.AAA,也支持com/taobao/test/AAA这样的格式,这样,我们从异常堆栈里面把类名拷贝过来的时候,不需要在手动把/替换为.啦。
    -
    sc 默认开启了子类匹配功能,也就是说所有当前类的子类也会被搜索出来,想要精确的匹配,请打开options disable-sub-class true开关
    +
    sc 默认开启了子类匹配功能,也就是说所有当前类的子类也会被搜索出来,想要精确的匹配,请打开options disable-sub-class true开关

    使用参考

    • 模糊搜索

      -
      $ sc demo.*
      +
      $ sc demo.*
       demo.MathGame
      -Affect(row-cnt:1) cost in 55 ms.
      +Affect(row-cnt:1) cost in 55 ms.
       
    • 打印类的详细信息

      -
      $ sc -d demo.MathGame
      +
      $ sc -d demo.MathGame
       class-info        demo.MathGame
       code-source       /private/tmp/arthas-demo.jar
       name              demo.MathGame
      -isInterface       false
      -isAnnotation      false
      -isEnum            false
      -isAnonymousClass  false
      -isArray           false
      -isLocalClass      false
      -isMemberClass     false
      -isPrimitive       false
      -isSynthetic       false
      +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
      +class-loader      +-sun.misc.Launcher$AppClassLoader@3d4eac69
      +                    +-sun.misc.Launcher$ExtClassLoader@66350f69
       classLoaderHash   3d4eac69
       
      -Affect(row-cnt:1) cost in 875 ms.
      +Affect(row-cnt:1) cost in 875 ms.
       
    • 打印出类的Field信息

      -
      $ sc -d -f demo.MathGame
      +
      $ sc -d -f demo.MathGame
       class-info        demo.MathGame
       code-source       /private/tmp/arthas-demo.jar
       name              demo.MathGame
      -isInterface       false
      -isAnnotation      false
      -isEnum            false
      -isAnonymousClass  false
      -isArray           false
      -isLocalClass      false
      -isMemberClass     false
      -isPrimitive       false
      -isSynthetic       false
      +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
      +class-loader      +-sun.misc.Launcher$AppClassLoader@3d4eac69
      +                    +-sun.misc.Launcher$ExtClassLoader@66350f69
       classLoaderHash   3d4eac69
       fields            modifierprivate,static
      -                  type    java.util.Random
      +                  type    java.util.Random
                         name    random
                         value   java.util.Random@522b4
                                 08a
       
                         modifierprivate
      -                  type    int
      +                  type    int
                         name    illegalArgumentCount
       
      -Affect(row-cnt:1) cost in 19 ms.
      +Affect(row-cnt:1) cost in 19 ms.
       
    • @@ -395,6 +396,15 @@ Affect(row-cnt:1) cost in + + + + + @@ -93,7 +94,7 @@
    • 进阶使用
    • 命令列表
    • 用户案例
    • -
    • Questions and answers
    • +
    • 常见问题
    • Fork me at GitHub
    • 参与贡献
    • Release Notes
    • @@ -248,6 +249,15 @@ + + + + + @@ -121,7 +122,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -199,7 +200,7 @@
    查看已加载类的方法信息

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

    -

    sm 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到。

    +

    sm 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到。

    参数说明

    @@ -230,7 +231,7 @@

    使用参考

    -
    $ sm java.lang.String
    +
    $ sm java.lang.String
     java.lang.String-><init>
     java.lang.String->equals
     java.lang.String->toString
    @@ -275,19 +276,19 @@ java.lang.String->toCharArray
     java.lang.String->format
     java.lang.String->copyValueOf
     java.lang.String->intern
    -Affect(row-cnt:44) cost in 1342 ms.
    +Affect(row-cnt:44) cost in 1342 ms.
     
    -
    $ sm -d java.lang.String toString
    +
    $ sm -d java.lang.String toString
      declaring-class  java.lang.String
      method-name      toString
      modifier         public
      annotation
      parameters
    - return           java.lang.String
    + return           java.lang.String
      exceptions
     
    -Affect(row-cnt:1) cost in 3 ms.
    +Affect(row-cnt:1) cost in 3 ms.
     
    @@ -366,6 +367,15 @@ Affect(row-cnt:1) cost in + + + + + @@ -127,7 +128,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -236,8 +237,8 @@ 执行次数限制 -

    这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。

    -

    观察的维度也比较多,主要体现在参数 advice 的数据结构上。Advice 参数最主要是封装了通知节点的所有信息。

    +

    这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。

    +

    观察的维度也比较多,主要体现在参数 advice 的数据结构上。Advice 参数最主要是封装了通知节点的所有信息。

    请参考表达式核心变量中关于该节点的描述。

    • 特殊用法请参考:https://github.com/alibaba/arthas/issues/71
    • @@ -248,44 +249,44 @@

      使用例子

      启动 Demo

      -

      启动快速入门里的arthas-demo。

      +

      启动快速入门里的arthas-demo。

      stack

      -
      $ stack demo.MathGame primeFactors
      +
      $ 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)
      +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)
       

      据条件表达式来过滤

      -
      $ stack demo.MathGame primeFactors 'params[0]<0' -n 2
      +
      $ stack demo.MathGame primeFactors 'params[0]<0' -n 2
       Press Ctrl+C to abort.
      -Affect(class-cnt:1 , method-cnt:1) cost in 30 ms.
      -ts=2018-12-04 01:34:27;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)
      +Affect(class-cnt:1 , method-cnt:1) cost in 30 ms.
      +ts=2018-12-04 01:34:27;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)
       
      -ts=2018-12-04 01:34:30;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)
      +ts=2018-12-04 01:34:30;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)
       
      -Command execution times exceed limit: 2, so command will exit. You can set it with -n option.
      +Command execution times exceed limit: 2, so command will exit. You can set it with -n option.
       

      据执行时间来过滤

      -
      $ stack demo.MathGame primeFactors '#cost>5'
      +
      $ 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)
      +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)
       
      @@ -365,6 +366,15 @@ Affect(class-cnt:1 , method-cnt:1) + + + + + @@ -93,7 +94,7 @@
    • 进阶使用
    • 命令列表
    • 用户案例
    • -
    • Questions and answers
    • +
    • 常见问题
    • Fork me at GitHub
    • 参与贡献
    • Release Notes
    • @@ -168,20 +169,20 @@

      启动 Arthas

      交互模式启动

      -
      ./as.sh
      +
      ./as.sh
       
      -
      ➜  bin git:(develop) ✗ ./as.sh
      +
      ➜  bin git:(develop) ✗ ./as.sh
       Found existing java process, please choose one and hit RETURN.
      -  [1]: 3088 org.jetbrains.idea.maven.server.RemoteMavenServer
      -* [2]: 12872 org.apache.catalina.startup.Bootstrap
      -  [3]: 2455
      -Attaching to 12872...
      +  [1]: 3088 org.jetbrains.idea.maven.server.RemoteMavenServer
      +* [2]: 12872 org.apache.catalina.startup.Bootstrap
      +  [3]: 2455
      +Attaching to 12872...
         ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
      - /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
      -|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
      -|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
      -`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
      + /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
      +|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
      +|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
      +`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
       $
       
      @@ -189,14 +190,14 @@ $

      非交互模式启动

      启动脚本如下:

      -
      ./as.sh <PID>[@IP:PORT]
      +
      ./as.sh <PID>[@IP:PORT]
       

      参数说明

      • PID:目标 Java 进程 ID(请确保执行当前执行命令的用户必须有足够的权限操作对应的 Java 进程)
      • -
      • IP:Arthas Server 侦听的地址,默认值是 127.00.1。Arthas允许多个用户同时访问,并且各自的命令不会相互干扰执行
      • +
      • IP:Arthas Server 侦听的地址,默认值是 127.00.1。Arthas允许多个用户同时访问,并且各自的命令不会相互干扰执行
      • PORT:目标服务器 Arthas Server 的端口号,默认的端口号是 3658
      @@ -217,21 +218,21 @@ $

      远程诊断

      服务器启动 Arthas Server 后,其他人可以使用 telnet 远程连接上去进程诊断,例如:

      -
      telnet 192.168.1.119 3658
      +
      telnet 192.168.1.119 3658
       

      sudo 支持

      成熟的线上管理环境一般都不会直接开放 JVM 部署用户权限给你,而是通过 sudo-list 来控制和监控用户的越权操作。由于 as.sh 脚本中会对当前用户的环境变量产生感知,所以需要加上 -H 参数

      -
      sudo -u admin -H ./as.sh 12345
      +
      sudo -u admin -H ./as.sh 12345
       

      Windows 环境支持

      -

      目前as.bat脚本只支持一个参数:pid

      -
      as.bat <pid>
      +

      目前as.bat脚本只支持一个参数:pid

      +
      as.bat <pid>
       
      @@ -302,6 +303,15 @@ $ + + + + + @@ -124,7 +125,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -200,30 +201,29 @@

    sysenv

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

    使用参考

    -
     USAGE:
    -   sysenv [-h] [env-name]
    +
     USAGE:
    +   sysenv [-h] [env-name]
     
    - SUMMARY:
    -   Display the system env.
    + SUMMARY:
    +   Display the system env.
     
    - EXAMPLES:
    -   sysenv
    -   sysenv USER
    + EXAMPLES:
    +   sysenv
    +   sysenv USER
     
    - WIKI:
    -   https://alibaba.github.io/arthas/sysenv
    + WIKI:
    +   https://alibaba.github.io/arthas/sysenv
     
    - OPTIONS:
    - -h, --help                                                 this help
    - <env-name>                                                 env name
    -
    + OPTIONS: + -h, --help this help + <env-name> env name

    查看所有环境变量

    -
    $ sysenv
    +
    $ sysenv
      KEY                      VALUE
     ----------------------------------------------------------------------------------------------------------------------------
      PATH                     /Users/admin/.sdkman/candidates/visualvm/current/bin:/Users/admin/.sdkman/candidates/ja
    @@ -255,17 +255,15 @@
      COLORFGBG                7;0
      HOME                     /Users/admin
      SHLVL                    1
    - AUTOJUMP_ERROR_PATH      /Users/admin/Library/autojump/errors.log
    -
    + AUTOJUMP_ERROR_PATH /Users/admin/Library/autojump/errors.log

    查看单个环境变量

    -
    支持通过TAB键自动补全
    -
    $ sysenv USER
    -USER=admin
    -
    +
    支持通过TAB键自动补全
    +
    $ sysenv USER
    +USER=admin
    @@ -344,6 +342,15 @@ USER=admin + + + + + @@ -125,7 +126,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -201,32 +202,31 @@

    sysprop

    -
    查看当前JVM的系统属性(System Property)
    +
    查看当前JVM的系统属性(System Property)

    使用参考

    -
     USAGE:
    -   sysprop [-h] [property-name] [property-value]
    +
     USAGE:
    +   sysprop [-h] [property-name] [property-value]
     
    - SUMMARY:
    -   Display, and change all the system properties.
    + SUMMARY:
    +   Display, and change all the system properties.
     
    - EXAMPLES:
    - sysprop
    - sysprop file.encoding
    - sysprop production.mode true
    + EXAMPLES:
    + sysprop
    + sysprop file.encoding
    + sysprop production.mode true
     
    - WIKI:
    -   https://alibaba.github.io/arthas/sysprop
    + WIKI:
    +   https://alibaba.github.io/arthas/sysprop
     
    - OPTIONS:
    - -h, --help                                  this help
    - <property-name>                             property name
    - <property-value>                            property value
    -
    + OPTIONS: + -h, --help this help + <property-name> property name + <property-value> property value

    查看所有属性

    -
    $ sysprop
    +
    $ sysprop
      KEY                                                  VALUE
     -------------------------------------------------------------------------------------------------------------------------------------
      java.runtime.name                                    Java(TM) SE Runtime Environment
    @@ -295,27 +295,24 @@
      java.vendor.url.bug                                  http://bugreport.sun.com/bugreport/
      sun.cpu.endian                                       little
      sun.io.unicode.encoding                              UnicodeBig
    - sun.cpu.isalist
    -
    + sun.cpu.isalist

    查看单个属性

    -
    支持通过TAB键自动补全
    -
    $ sysprop java.version
    -java.version=1.8.0_51
    -
    +
    支持通过TAB键自动补全
    +
    $ sysprop java.version
    +java.version=1.8.0_51

    修改单个属性

    -
    $ sysprop user.country
    +
    $ sysprop user.country
     user.country=US
     $ sysprop user.country CN
     Successfully changed the system property.
    -user.country=CN
    -
    +user.country=CN
    @@ -394,6 +391,15 @@ user.country=CN + + + + + @@ -128,7 +129,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -236,7 +237,7 @@
    cpu占比是如何统计出来的?
    这里的cpu统计的是,一段采样间隔内,当前JVM里各个线程所占用的cpu时间占总cpu时间的百分比。其计算方法为: -首先进行一次采样,获得所有线程的cpu的使用时间(调用的是java.lang.management.ThreadMXBean#getThreadCpuTime这个接口),然后睡眠一段时间,默认100ms,可以通过-i参数指定,然后再采样一次,最后得出这段时间内各个线程消耗的cpu时间情况,最后算出百分比。
    +首先进行一次采样,获得所有线程的cpu的使用时间(调用的是java.lang.management.ThreadMXBean#getThreadCpuTime这个接口),然后睡眠一段时间,默认100ms,可以通过-i参数指定,然后再采样一次,最后得出这段时间内各个线程消耗的cpu时间情况,最后算出百分比。
    注意: 这个统计也会产生一定的开销(JDK这个接口本身开销比较大),因此会看到as的线程占用一定的百分比,为了降低统计自身的开销带来的影响,可以把采样间隔拉长一些,比如5000毫秒。
    @@ -246,134 +247,134 @@

    使用参考

    支持一键展示当前最忙的前N个线程并打印堆栈:

    -
    $ thread -n 3
    -"as-command-execute-daemon" Id=29 cpuUsage=75% RUNNABLE
    -    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    -    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
    -    at com.taobao.arthas.core.command.monitor200.ThreadCommand$1.action(ThreadCommand.java:58)
    -    at com.taobao.arthas.core.command.handler.AbstractCommandHandler.execute(AbstractCommandHandler.java:238)
    -    at com.taobao.arthas.core.command.handler.DefaultCommandHandler.handleCommand(DefaultCommandHandler.java:67)
    -    at com.taobao.arthas.core.server.ArthasServer$4.run(ArthasServer.java:276)
    -    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    -    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    -    at java.lang.Thread.run(Thread.java:745)
    +
    $ thread -n 3
    +"as-command-execute-daemon" Id=29 cpuUsage=75% RUNNABLE
    +    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    +    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
    +    at com.taobao.arthas.core.command.monitor200.ThreadCommand$1.action(ThreadCommand.java:58)
    +    at com.taobao.arthas.core.command.handler.AbstractCommandHandler.execute(AbstractCommandHandler.java:238)
    +    at com.taobao.arthas.core.command.handler.DefaultCommandHandler.handleCommand(DefaultCommandHandler.java:67)
    +    at com.taobao.arthas.core.server.ArthasServer$4.run(ArthasServer.java:276)
    +    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    +    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    +    at java.lang.Thread.run(Thread.java:745)
     
    -    Number of locked synchronizers = 1
    -    - java.util.concurrent.ThreadPoolExecutor$Worker@6cd0b6f8
    +    Number of locked synchronizers = 1
    +    - java.util.concurrent.ThreadPoolExecutor$Worker@6cd0b6f8
     
    -"as-session-expire-daemon" Id=25 cpuUsage=24% TIMED_WAITING
    -    at java.lang.Thread.sleep(Native Method)
    -    at com.taobao.arthas.core.server.DefaultSessionManager$2.run(DefaultSessionManager.java:85)
    +"as-session-expire-daemon" Id=25 cpuUsage=24% TIMED_WAITING
    +    at java.lang.Thread.sleep(Native Method)
    +    at com.taobao.arthas.core.server.DefaultSessionManager$2.run(DefaultSessionManager.java:85)
     
    -"Reference Handler" Id=2 cpuUsage=0% WAITING on java.lang.ref.Reference$Lock@69ba0f27
    -    at java.lang.Object.wait(Native Method)
    -    -  waiting on java.lang.ref.Reference$Lock@69ba0f27
    -    at java.lang.Object.wait(Object.java:503)
    -    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
    +"Reference Handler" Id=2 cpuUsage=0% WAITING on java.lang.ref.Reference$Lock@69ba0f27
    +    at java.lang.Object.wait(Native Method)
    +    -  waiting on java.lang.ref.Reference$Lock@69ba0f27
    +    at java.lang.Object.wait(Object.java:503)
    +    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
     

    当没有参数时,显示所有线程的信息。

    -
    $ thread
    -Threads Total: 16, NEW: 0, RUNNABLE: 7, BLOCKED: 0, WAITING: 5, TIMED_WAITING: 4, TERMINATED: 0
    +
    $ thread
    +Threads Total: 16, NEW: 0, RUNNABLE: 7, BLOCKED: 0, WAITING: 5, TIMED_WAITING: 4, TERMINATED: 0
     ID         NAME                             GROUP                 PRIORITY   STATE      %CPU       TIME       INTERRUPTE DAEMON
    -30         as-command-execute-daemon        system                9          RUNNABLE   72         0:0        false      true
    -23         as-session-expire-daemon         system                9          TIMED_WAIT 27         0:0        false      true
    -22         Attach Listener                  system                9          RUNNABLE   0          0:0        false      true
    -11         pool-2-thread-1                  main                  5          TIMED_WAIT 0          0:0        false      false
    -12         Thread-2                         main                  5          RUNNABLE   0          0:0        false      true
    -13         pool-3-thread-1                  main                  5          TIMED_WAIT 0          0:0        false      false
    -25         as-selector-daemon               system                9          RUNNABLE   0          0:0        false      true
    -14         Thread-3                         main                  5          TIMED_WAIT 0          0:0        false      false
    -26         pool-5-thread-1                  system                5          WAITING    0          0:0        false      false
    -15         Thread-4                         main                  5          RUNNABLE   0          0:0        false      false
    -1          main                             main                  5          WAITING    0          0:2        false      false
    -2          Reference Handler                system                10         WAITING    0          0:0        false      true
    -3          Finalizer                        system                8          WAITING    0          0:0        false      true
    -4          Signal Dispatcher                system                9          RUNNABLE   0          0:0        false      true
    -20         NonBlockingInputStreamThread     main                  5          WAITING    0          0:0        false      true
    -21         Thread-8                         main                  5          RUNNABLE   0          0:0        false      true
    +30         as-command-execute-daemon        system                9          RUNNABLE   72         0:0        false      true
    +23         as-session-expire-daemon         system                9          TIMED_WAIT 27         0:0        false      true
    +22         Attach Listener                  system                9          RUNNABLE   0          0:0        false      true
    +11         pool-2-thread-1                  main                  5          TIMED_WAIT 0          0:0        false      false
    +12         Thread-2                         main                  5          RUNNABLE   0          0:0        false      true
    +13         pool-3-thread-1                  main                  5          TIMED_WAIT 0          0:0        false      false
    +25         as-selector-daemon               system                9          RUNNABLE   0          0:0        false      true
    +14         Thread-3                         main                  5          TIMED_WAIT 0          0:0        false      false
    +26         pool-5-thread-1                  system                5          WAITING    0          0:0        false      false
    +15         Thread-4                         main                  5          RUNNABLE   0          0:0        false      false
    +1          main                             main                  5          WAITING    0          0:2        false      false
    +2          Reference Handler                system                10         WAITING    0          0:0        false      true
    +3          Finalizer                        system                8          WAITING    0          0:0        false      true
    +4          Signal Dispatcher                system                9          RUNNABLE   0          0:0        false      true
    +20         NonBlockingInputStreamThread     main                  5          WAITING    0          0:0        false      true
    +21         Thread-8                         main                  5          RUNNABLE   0          0:0        false      true
     

    thread id, 显示指定线程的运行堆栈

    -
    $ thread 1
    -"main" Id=1 WAITING on java.util.concurrent.CountDownLatch$Sync@29fafb28
    -    at sun.misc.Unsafe.park(Native Method)
    -    -  waiting on java.util.concurrent.CountDownLatch$Sync@29fafb28
    -    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    -    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    -    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
    -    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
    -    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
    +
    $ thread 1
    +"main" Id=1 WAITING on java.util.concurrent.CountDownLatch$Sync@29fafb28
    +    at sun.misc.Unsafe.park(Native Method)
    +    -  waiting on java.util.concurrent.CountDownLatch$Sync@29fafb28
    +    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    +    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    +    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
    +    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
    +    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
     

    thread -b, 找出当前阻塞其他线程的线程

    -

    有时候我们发现应用卡住了, 通常是由于某个线程拿住了某个锁, 并且其他线程都在等待这把锁造成的。 为了排查这类问题, arthas提供了thread -b, 一键找出那个罪魁祸首。

    -
    $ thread -b
    -"http-bio-8080-exec-4" Id=27 TIMED_WAITING
    -    at java.lang.Thread.sleep(Native Method)
    -    at test.arthas.TestThreadBlocking.doGet(TestThreadBlocking.java:22)
    -    -  locked java.lang.Object@725be470 <---- but blocks 4 other threads!
    -    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    -    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    -    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    -    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    -    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    -    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    -    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    -    at test.filter.TestDurexFilter.doFilter(TestDurexFilter.java:46)
    -    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    -    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    -    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    -    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    -    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    -    at com.taobao.tomcat.valves.ContextLoadFilterValve$FilterChainAdapter.doFilter(ContextLoadFilterValve.java:191)
    -    at com.taobao.eagleeye.EagleEyeFilter.doFilter(EagleEyeFilter.java:81)
    -    at com.taobao.tomcat.valves.ContextLoadFilterValve.invoke(ContextLoadFilterValve.java:150)
    -    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    -    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    -    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    -    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:429)
    -    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
    -    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    -    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
    +

    有时候我们发现应用卡住了, 通常是由于某个线程拿住了某个锁, 并且其他线程都在等待这把锁造成的。 为了排查这类问题, arthas提供了thread -b, 一键找出那个罪魁祸首。

    +
    $ thread -b
    +"http-bio-8080-exec-4" Id=27 TIMED_WAITING
    +    at java.lang.Thread.sleep(Native Method)
    +    at test.arthas.TestThreadBlocking.doGet(TestThreadBlocking.java:22)
    +    -  locked java.lang.Object@725be470 <---- but blocks 4 other threads!
    +    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    +    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    +    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    +    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    +    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    +    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    +    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    +    at test.filter.TestDurexFilter.doFilter(TestDurexFilter.java:46)
    +    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    +    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    +    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    +    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    +    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    +    at com.taobao.tomcat.valves.ContextLoadFilterValve$FilterChainAdapter.doFilter(ContextLoadFilterValve.java:191)
    +    at com.taobao.eagleeye.EagleEyeFilter.doFilter(EagleEyeFilter.java:81)
    +    at com.taobao.tomcat.valves.ContextLoadFilterValve.invoke(ContextLoadFilterValve.java:150)
    +    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    +    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    +    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    +    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:429)
    +    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
    +    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    +    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
         -  locked org.apache.tomcat.util.net.SocketWrapper@7127ee12
    -    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    -    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    -    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    -    at java.lang.Thread.run(Thread.java:745)
    +    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    +    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    +    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    +    at java.lang.Thread.run(Thread.java:745)
     
    -    Number of locked synchronizers = 1
    -    - java.util.concurrent.ThreadPoolExecutor$Worker@31a6493e
    +    Number of locked synchronizers = 1
    +    - java.util.concurrent.ThreadPoolExecutor$Worker@31a6493e
     
    -
    注意, 目前只支持找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持。
    +
    注意, 目前只支持找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持。

    thread -i, 指定采样时间间隔

    -
    $ thread -n 3 -i 1000
    -"as-command-execute-daemon" Id=4759 cpuUsage=23% RUNNABLE
    -    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    -    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
    -    at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:133)
    -    at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:79)
    -    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:96)
    -    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:27)
    -    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:125)
    -    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:122)
    -    at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:332)
    -    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:756)
    +
    $ thread -n 3 -i 1000
    +"as-command-execute-daemon" Id=4759 cpuUsage=23% RUNNABLE
    +    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    +    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
    +    at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:133)
    +    at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:79)
    +    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:96)
    +    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:27)
    +    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:125)
    +    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:122)
    +    at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:332)
    +    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:756)
     
    -    Number of locked synchronizers = 1
    -    - java.util.concurrent.ThreadPoolExecutor$Worker@546aeec1
    +    Number of locked synchronizers = 1
    +    - java.util.concurrent.ThreadPoolExecutor$Worker@546aeec1
     ...
     
    @@ -454,6 +455,15 @@ ID NAME GROUP PRIORITY STA + + + + + @@ -128,7 +129,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -205,7 +206,7 @@

    trace

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

    trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。

    +

    trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。

    参数说明

    @@ -241,73 +242,73 @@ -
    方法执行耗时

    这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。

    -

    观察的维度也比较多,主要体现在参数 advice 的数据结构上。Advice 参数最主要是封装了通知节点的所有信息。

    +

    这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。

    +

    观察的维度也比较多,主要体现在参数 advice 的数据结构上。Advice 参数最主要是封装了通知节点的所有信息。

    请参考表达式核心变量中关于该节点的描述。

    -

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

    +

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

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

    注意事项

    -

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

    +

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

    使用参考

    启动 Demo

    -

    启动快速入门里的arthas-demo。

    +

    启动快速入门里的arthas-demo。

    trace函数

    -
    $ trace demo.MathGame run
    +
    $ trace demo.MathGame run
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 42 ms.
    -`---ts=2018-12-04 00:44:17;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
    -    `---[10.611029ms] demo.MathGame:run()
    -        +---[0.05638ms] java.util.Random:nextInt()
    -        +---[10.036885ms] demo.MathGame:primeFactors()
    -        `---[0.170316ms] demo.MathGame:print()
    +Affect(class-cnt:1 , method-cnt:1) cost in 42 ms.
    +`---ts=2018-12-04 00:44:17;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
    +    `---[10.611029ms] demo.MathGame:run()
    +        +---[0.05638ms] java.util.Random:nextInt()
    +        +---[10.036885ms] demo.MathGame:primeFactors()
    +        `---[0.170316ms] demo.MathGame:print()
     

    过滤掉jdk的函数

    -
    $ trace -j  demo.MathGame run
    +
    $ trace -j  demo.MathGame run
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 31 ms.
    -`---ts=2018-12-04 01:09:14;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
    -    `---[5.190646ms] demo.MathGame:run()
    -        +---[4.465779ms] demo.MathGame:primeFactors()
    -        `---[0.375324ms] demo.MathGame:print()
    +Affect(class-cnt:1 , method-cnt:1) cost in 31 ms.
    +`---ts=2018-12-04 01:09:14;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
    +    `---[5.190646ms] demo.MathGame:run()
    +        +---[4.465779ms] demo.MathGame:primeFactors()
    +        `---[0.375324ms] demo.MathGame:print()
     
      -
    • -j: jdkMethodSkip, skip jdk method trace
    • +
    • -j: jdkMethodSkip, skip jdk method trace

    据调用耗时过滤

    -
    $ trace demo.MathGame run '#cost > 10'
    +
    $ 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()
    +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()
     
    只会展示耗时大于4ms的调用路径,有助于在排查问题的时候,只关注异常情况
      -
    • 是不是很眼熟,没错,在 JProfiler 等收费软件中你曾经见识类似的功能,这里你将可以通过命令就能打印出指定调用路径。 友情提醒下,trace 在执行的过程中本身是会有一定的性能开销,在统计的报告中并未像 JProfiler 一样预先减去其自身的统计开销。所以这统计出来有些许的不准,渲染路径上调用的类、方法越多,性能偏差越大。但还是能让你看清一些事情的。
    • -
    • [12.033735ms] 的含义,12.033735 的含义是:当前节点在当前步骤的耗时,单位为毫秒
    • -
    • [0,0,0ms,11]xxx:yyy() [throws Exception],对该方法中相同的方法调用进行了合并,0,0,0ms,11 表示方法调用耗时,min,max,total,count;throws Exception 表明该方法调用中存在异常返回
    • +
    • 是不是很眼熟,没错,在 JProfiler 等收费软件中你曾经见识类似的功能,这里你将可以通过命令就能打印出指定调用路径。 友情提醒下,trace 在执行的过程中本身是会有一定的性能开销,在统计的报告中并未像 JProfiler 一样预先减去其自身的统计开销。所以这统计出来有些许的不准,渲染路径上调用的类、方法越多,性能偏差越大。但还是能让你看清一些事情的。
    • +
    • [12.033735ms] 的含义,12.033735 的含义是:当前节点在当前步骤的耗时,单位为毫秒
    • +
    • [0,0,0ms,11]xxx:yyy() [throws Exception],对该方法中相同的方法调用进行了合并,0,0,0ms,11 表示方法调用耗时,min,max,total,count;throws Exception 表明该方法调用中存在异常返回
    • 这里存在一个统计不准确的问题,就是所有方法耗时加起来可能会小于该监测方法的总耗时,这个是由于 Arthas 本身的逻辑会有一定的耗时
    @@ -387,6 +388,15 @@ Affect(class-cnt:1 , method-cnt:1) + + + + + @@ -127,7 +128,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -204,39 +205,39 @@

    tt

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

    watch 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。

    +

    watch 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。

    这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。

    于是乎,TimeTunnel 命令就诞生了。

    使用参考

    启动 Demo

    -

    启动快速入门里的arthas-demo。

    +

    启动快速入门里的arthas-demo。

    记录调用

    对于一个最基本的使用来说,就是记录下当前方法的每次调用环境现场。

    -
    $ tt -t demo.MathGame primeFactors
    +
    $ tt -t demo.MathGame primeFactors
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
    - INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
    +Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
    + INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
     -------------------------------------------------------------------------------------------------------------------------------------
    - 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
    + 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
     
    • 命令参数解析

        -
      • -t

        -

        tt 命令有很多个主参数,-t 就是其中之一。这个参数的表明希望记录下类 *Test 的 print 方法的每次执行情况。

        +
      • -t

        +

        tt 命令有很多个主参数,-t 就是其中之一。这个参数的表明希望记录下类 *Test 的 print 方法的每次执行情况。

      • -
      • -n 3

        -

        当你执行一个调用量不高的方法时可能你还能有足够的时间用 CTRL+C 中断 tt 命令记录的过程,但如果遇到调用量非常大的方法,瞬间就能将你的 JVM 内存撑爆。

        -

        此时你可以通过 -n 参数指定你需要记录的次数,当达到记录次数时 Arthas 会主动中断tt命令的记录过程,避免人工操作无法停止的情况。

        +
      • -n 3

        +

        当你执行一个调用量不高的方法时可能你还能有足够的时间用 CTRL+C 中断 tt 命令记录的过程,但如果遇到调用量非常大的方法,瞬间就能将你的 JVM 内存撑爆。

        +

        此时你可以通过 -n 参数指定你需要记录的次数,当达到记录次数时 Arthas 会主动中断tt命令的记录过程,避免人工操作无法停止的情况。

    • @@ -291,97 +292,97 @@ Affect(class-cnt:1 , method-cnt:1)
    • Arthas 似乎很难区分出重载的方法
    • 我只需要观察特定参数,但是 tt 却全部都给我记录了下来
    -

    条件表达式也是用 OGNL 来编写,核心的判断对象依然是 Advice 对象。除了 tt 命令之外,watch、trace、stack 命令也都支持条件表达式。

    +

    条件表达式也是用 OGNL 来编写,核心的判断对象依然是 Advice 对象。除了 tt 命令之外,watch、trace、stack 命令也都支持条件表达式。

  • 解决方法重载

    -

    tt -t *Test print params[0].length==1

    +

    tt -t *Test print params[0].length==1

    通过制定参数个数的形式解决不同的方法签名,如果参数个数一样,你还可以这样写

    -

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

    +

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

  • 解决指定参数

    -

    tt -t *Test print params[0].mobile=="13989838402"

    +

    tt -t *Test print params[0].mobile=="13989838402"

  • -
  • 构成条件表达式的 Advice 对象

    -

    前边看到了很多条件表达式中,都适用了 params[0],有关这个变量的介绍,请参考表达式核心变量

    +
  • 构成条件表达式的 Advice 对象

    +

    前边看到了很多条件表达式中,都适用了 params[0],有关这个变量的介绍,请参考表达式核心变量

  • 检索调用记录

    -

    当你用 tt 记录了一大片的时间片段之后,你希望能从中筛选出自己需要的时间片段,这个时候你就需要对现有记录进行检索。

    +

    当你用 tt 记录了一大片的时间片段之后,你希望能从中筛选出自己需要的时间片段,这个时候你就需要对现有记录进行检索。

    假设我们有这些记录

    -
    $ tt -l
    - INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
    +
    $ tt -l
    + INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
     -------------------------------------------------------------------------------------------------------------------------------------
    - 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
    -                              9
    - 1005    2018-12-04 11:15:43  0.4776    false   true     0x4b67cf4d     MathGame                       primeFactors
    -Affect(row-cnt:6) cost in 4 ms.
    + 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
    +                              9
    + 1005    2018-12-04 11:15:43  0.4776    false   true     0x4b67cf4d     MathGame                       primeFactors
    +Affect(row-cnt:6) cost in 4 ms.
     
    -

    我需要筛选出 primeFactors 方法的调用信息

    -
    $ tt -s 'method.name=="primeFactors"'
    - INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
    +

    我需要筛选出 primeFactors 方法的调用信息

    +
    $ tt -s 'method.name=="primeFactors"'
    + INDEX   TIMESTAMP            COST(ms)  IS-RET  IS-EXP   OBJECT         CLASS                          METHOD
     -------------------------------------------------------------------------------------------------------------------------------------
    - 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
    - 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
    -                              9
    - 1005    2018-12-04 11:15:43  0.4776    false   true     0x4b67cf4d     MathGame                       primeFactors
    -Affect(row-cnt:6) cost in 607 ms.
    + 1000    2018-12-04 11:15:38  1.096236  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1001    2018-12-04 11:15:39  0.191848  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1002    2018-12-04 11:15:40  0.069523  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1003    2018-12-04 11:15:41  0.186073  false   true     0x4b67cf4d     MathGame                       primeFactors
    + 1004    2018-12-04 11:15:42  17.76437  true    false    0x4b67cf4d     MathGame                       primeFactors
    +                              9
    + 1005    2018-12-04 11:15:43  0.4776    false   true     0x4b67cf4d     MathGame                       primeFactors
    +Affect(row-cnt:6) cost in 607 ms.
     
    -

    你需要一个 -s 参数。同样的,搜索表达式的核心对象依旧是 Advice 对象。

    +

    你需要一个 -s 参数。同样的,搜索表达式的核心对象依旧是 Advice 对象。

    查看调用信息

    -

    对于具体一个时间片的信息而言,你可以通过 -i 参数后边跟着对应的 INDEX 编号查看到他的详细信息。

    -
    $ tt -i 1003
    - INDEX            1003
    - GMT-CREATE       2018-12-04 11:15:41
    - COST(ms)         0.186073
    +

    对于具体一个时间片的信息而言,你可以通过 -i 参数后边跟着对应的 INDEX 编号查看到他的详细信息。

    +
    $ tt -i 1003
    + INDEX            1003
    + GMT-CREATE       2018-12-04 11:15:41
    + COST(ms)         0.186073
      OBJECT           0x4b67cf4d
      CLASS            demo.MathGame
      METHOD           primeFactors
    - IS-RETURN        false
    - IS-EXCEPTION     true
    - PARAMETERS[0]    @Integer[-564322413]
    - THROW-EXCEPTION  java.lang.IllegalArgumentException: number is: -564322413, need >= 2
    -                      at demo.MathGame.primeFactors(MathGame.java:46)
    -                      at demo.MathGame.run(MathGame.java:24)
    -                      at demo.MathGame.main(MathGame.java:16)
    + IS-RETURN        false
    + IS-EXCEPTION     true
    + PARAMETERS[0]    @Integer[-564322413]
    + THROW-EXCEPTION  java.lang.IllegalArgumentException: number is: -564322413, need >= 2
    +                      at demo.MathGame.primeFactors(MathGame.java:46)
    +                      at demo.MathGame.run(MathGame.java:24)
    +                      at demo.MathGame.main(MathGame.java:16)
     
    -Affect(row-cnt:1) cost in 11 ms.
    +Affect(row-cnt:1) cost in 11 ms.
     

    重做一次调用

    当你稍稍做了一些调整之后,你可能需要前端系统重新触发一次你的调用,此时得求爷爷告奶奶的需要前端配合联调的同学再次发起一次调用。而有些场景下,这个调用不是这么好触发的。

    -

    tt 命令由于保存了当时调用的所有现场信息,所以我们可以自己主动对一个 INDEX 编号的时间片自主发起一次调用,从而解放你的沟通成本。此时你需要 -p 参数。

    -
    $ tt -i 1004 -p
    - RE-INDEX       1004
    - GMT-REPLAY     2018-12-04 11:26:00
    +

    tt 命令由于保存了当时调用的所有现场信息,所以我们可以自己主动对一个 INDEX 编号的时间片自主发起一次调用,从而解放你的沟通成本。此时你需要 -p 参数。

    +
    $ tt -i 1004 -p
    + RE-INDEX       1004
    + GMT-REPLAY     2018-12-04 11:26:00
      OBJECT         0x4b67cf4d
      CLASS          demo.MathGame
      METHOD         primeFactors
    - PARAMETERS[0]  @Integer[946738738]
    - IS-RETURN      true
    - IS-EXCEPTION   false
    - RETURN-OBJ     @ArrayList[
    -                    @Integer[2],
    -                    @Integer[11],
    -                    @Integer[17],
    -                    @Integer[2531387],
    -                ]
    -Time fragment[1004] successfully replayed.
    -Affect(row-cnt:1) cost in 14 ms.
    + PARAMETERS[0]  @Integer[946738738]
    + IS-RETURN      true
    + IS-EXCEPTION   false
    + RETURN-OBJ     @ArrayList[
    +                    @Integer[2],
    +                    @Integer[11],
    +                    @Integer[17],
    +                    @Integer[2531387],
    +                ]
    +Time fragment[1004] successfully replayed.
    +Affect(row-cnt:1) cost in 14 ms.
     

    你会发现结果虽然一样,但调用的路径发生了变化,有原来的程序发起变成了 Arthas 自己的内部线程发起的调用了。

    @@ -393,7 +394,7 @@ Affect(row-cnt:1) cost in 一些常见的 CASE 比如:鹰眼的 TraceId 等。

  • 引用的对象

    -

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

    +

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

  • @@ -475,6 +476,15 @@ Affect(row-cnt:1) cost in + + + + + @@ -115,7 +116,7 @@
  • 观察方法出参和返回值
  • 观察方法入参
  • 同时观察方法调用前和方法返回后
  • -
  • 调整-x的值,观察具体的方法参数值
  • +
  • 调整-x的值,观察具体的方法参数值
  • 条件表达式的例子
  • 观察异常信息的例子
  • 按照耗时进行过滤
  • @@ -132,7 +133,7 @@
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -209,7 +210,7 @@

    watch

    方法执行数据观测
    -

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

    +

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

    参数说明

    watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象

    @@ -262,56 +263,56 @@ 指定输出结果的属性遍历深度,默认为 1 -

    这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。

    -

    观察的维度也比较多,主要体现在参数 advice 的数据结构上。Advice 参数最主要是封装了通知节点的所有信息。请参考表达式核心变量中关于该节点的描述。

    +

    这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。

    +

    观察的维度也比较多,主要体现在参数 advice 的数据结构上。Advice 参数最主要是封装了通知节点的所有信息。请参考表达式核心变量中关于该节点的描述。

    特别说明:

      -
    • watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后
    • -
    • 4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
    • -
    • 这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参
    • -
    • 当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在
    • +
    • watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后
    • +
    • 4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
    • +
    • 这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参
    • +
    • 当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在

    使用参考

    启动 Demo

    -

    启动快速入门里的arthas-demo。

    +

    启动快速入门里的arthas-demo。

    观察方法出参和返回值

    -
    $ watch demo.MathGame primeFactors "{params,returnObj}" -x 2
    +
    $ watch demo.MathGame primeFactors "{params,returnObj}" -x 2
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 44 ms.
    -ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[
    -    @Object[][
    -        @Integer[535629513],
    -    ],
    -    @ArrayList[
    -        @Integer[3],
    -        @Integer[19],
    -        @Integer[191],
    -        @Integer[49199],
    -    ],
    -]
    +Affect(class-cnt:1 , method-cnt:1) cost in 44 ms.
    +ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[
    +    @Object[][
    +        @Integer[535629513],
    +    ],
    +    @ArrayList[
    +        @Integer[3],
    +        @Integer[19],
    +        @Integer[191],
    +        @Integer[49199],
    +    ],
    +]
     

    观察方法入参

    -
    $ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b
    +
    $ 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],
    -    ],
    +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,
    -]
    +]
     
      @@ -320,91 +321,91 @@ Affect(class-cnt:1 , method-cnt:1)

    同时观察方法调用前和方法返回后

    -
    $ watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2
    +
    $ 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[1544665400],
    -    ],
    -    @MathGame[
    -        random=@Random[java.util.Random@522b408a],
    -        illegalArgumentCount=@Integer[13038],
    -    ],
    +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[1544665400],
    +    ],
    +    @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[1544665400],
    -    ],
    -    @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],
    -    ],
    -]
    +]
    +ts=2018-12-03 19:29:54; [cost=4.277392ms] result=@ArrayList[
    +    @Object[][
    +        @Integer[1544665400],
    +    ],
    +    @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],
    +    ],
    +]
     
      -
    • 参数里-n 2,表示只执行两次
    • +
    • 参数里-n 2,表示只执行两次
    • 这里输出结果中,第一次输出的是方法调用前的观察表达式的结果,第二次输出的是方法返回后的表达式的结果
    • -
    • 结果的顺序和命令中 -s -b 的顺序没有关系,只与事件本身的先后顺序有关
    • +
    • 结果的顺序和命令中 -s -b 的顺序没有关系,只与事件本身的先后顺序有关
    -

    调整-x的值,观察具体的方法参数值

    -
    $ watch demo.MathGame primeFactors "{params,target}" -x 3
    +

    调整-x的值,观察具体的方法参数值

    +
    $ watch demo.MathGame primeFactors "{params,target}" -x 3
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 58 ms.
    -ts=2018-12-03 19:34:19; [cost=0.587833ms] result=@ArrayList[
    -    @Object[][
    -        @Integer[47816758],
    -    ],
    -    @MathGame[
    -        random=@Random[
    -            serialVersionUID=@Long[3905348978240129619],
    -            seed=@AtomicLong[3133719055989],
    -            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@2eaa1027],
    -            seedOffset=@Long[24],
    -        ],
    -        illegalArgumentCount=@Integer[13159],
    -    ],
    -]
    +Affect(class-cnt:1 , method-cnt:1) cost in 58 ms.
    +ts=2018-12-03 19:34:19; [cost=0.587833ms] result=@ArrayList[
    +    @Object[][
    +        @Integer[47816758],
    +    ],
    +    @MathGame[
    +        random=@Random[
    +            serialVersionUID=@Long[3905348978240129619],
    +            seed=@AtomicLong[3133719055989],
    +            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@2eaa1027],
    +            seedOffset=@Long[24],
    +        ],
    +        illegalArgumentCount=@Integer[13159],
    +    ],
    +]
     
      -
    • -x表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是1。
    • +
    • -x表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是1。

    条件表达式的例子

    -
    $ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"
    +
    $ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 68 ms.
    -ts=2018-12-03 19:36:04; [cost=0.530255ms] result=@ArrayList[
    -    @Integer[-18178089],
    -    @MathGame[demo.MathGame@41cf53f9],
    -]
    +Affect(class-cnt:1 , method-cnt:1) cost in 68 ms.
    +ts=2018-12-03 19:36:04; [cost=0.530255ms] result=@ArrayList[
    +    @Integer[-18178089],
    +    @MathGame[demo.MathGame@41cf53f9],
    +]
     
      @@ -413,62 +414,62 @@ Affect(class-cnt:1 , method-cnt:1)

    观察异常信息的例子

    -
    $ watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2
    +
    $ watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 62 ms.
    -ts=2018-12-03 19:38:00; [cost=1.414993ms] result=@ArrayList[
    -    @Integer[-1120397038],
    -    java.lang.IllegalArgumentException: number is: -1120397038, need >= 2
    -    at demo.MathGame.primeFactors(MathGame.java:46)
    -    at demo.MathGame.run(MathGame.java:24)
    -    at demo.MathGame.main(MathGame.java:16)
    +Affect(class-cnt:1 , method-cnt:1) cost in 62 ms.
    +ts=2018-12-03 19:38:00; [cost=1.414993ms] result=@ArrayList[
    +    @Integer[-1120397038],
    +    java.lang.IllegalArgumentException: number is: -1120397038, need >= 2
    +    at demo.MathGame.primeFactors(MathGame.java:46)
    +    at demo.MathGame.run(MathGame.java:24)
    +    at demo.MathGame.main(MathGame.java:16)
     ,
    -]
    +]
     
      -
    • -e表示抛出异常时才触发
    • -
    • express中,表示异常信息的变量是throwExp
    • +
    • -e表示抛出异常时才触发
    • +
    • express中,表示异常信息的变量是throwExp

    按照耗时进行过滤

    -
    $ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2
    +
    $ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
    -ts=2018-12-03 19:40:28; [cost=2112.168897ms] result=@ArrayList[
    -    @Object[][
    -        @Integer[2141897465],
    -    ],
    -    @ArrayList[
    -        @Integer[5],
    -        @Integer[428379493],
    -    ],
    -]
    +Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
    +ts=2018-12-03 19:40:28; [cost=2112.168897ms] result=@ArrayList[
    +    @Object[][
    +        @Integer[2141897465],
    +    ],
    +    @ArrayList[
    +        @Integer[5],
    +        @Integer[428379493],
    +    ],
    +]
     
      -
    • #cost>200(单位是ms)表示只有当耗时大于200ms时才会输出,过滤掉执行时间小于200ms的调用
    • +
    • #cost>200(单位是ms)表示只有当耗时大于200ms时才会输出,过滤掉执行时间小于200ms的调用

    观察当前对象中的属性

    -

    如果想查看方法运行前后,当前对象中的属性,可以使用target关键字,代表当前对象

    -
    $ watch demo.MathGame primeFactors 'target'
    +

    如果想查看方法运行前后,当前对象中的属性,可以使用target关键字,代表当前对象

    +
    $ watch demo.MathGame primeFactors 'target'
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 52 ms.
    -ts=2018-12-03 19:41:52; [cost=0.477882ms] result=@MathGame[
    -    random=@Random[java.util.Random@522b408a],
    -    illegalArgumentCount=@Integer[13355],
    -]
    +Affect(class-cnt:1 , method-cnt:1) cost in 52 ms.
    +ts=2018-12-03 19:41:52; [cost=0.477882ms] result=@MathGame[
    +    random=@Random[java.util.Random@522b408a],
    +    illegalArgumentCount=@Integer[13355],
    +]
     
    -

    然后使用target.field_name访问当前对象的某个属性

    -
    $ watch demo.MathGame primeFactors 'target.illegalArgumentCount'
    +

    然后使用target.field_name访问当前对象的某个属性

    +
    $ watch demo.MathGame primeFactors 'target.illegalArgumentCount'
     Press Ctrl+C to abort.
    -Affect(class-cnt:1 , method-cnt:1) cost in 67 ms.
    -ts=2018-12-03 20:04:34; [cost=131.303498ms] result=@Integer[8]
    -ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8]
    +Affect(class-cnt:1 , method-cnt:1) cost in 67 ms.
    +ts=2018-12-03 20:04:34; [cost=131.303498ms] result=@Integer[8]
    +ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8]
     
    @@ -548,6 +549,15 @@ Affect(class-cnt:1 , method-cnt:1) + + + + + @@ -109,7 +110,7 @@
  • 命令列表
  • 用户案例
  • -
  • Questions and answers
  • +
  • 常见问题
  • Fork me at GitHub
  • 参与贡献
  • Release Notes
  • @@ -263,6 +264,15 @@ + + + +