JVM技术专题精心准备了一套JVM分析工具的锦囊「下篇」

Posted 浩宇の天尚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM技术专题精心准备了一套JVM分析工具的锦囊「下篇」相关的知识,希望对你有一定的参考价值。

官方文档:

  • 中:https://alibaba.github.io/arthas/
  • 英:https://alibaba.github.io/arthas/en/

定义说明:

  • Arthas 是Alibaba开源的Java诊断工具,它可以帮助我们解决在线环境的以下问题。

    • 监控到JVM的实时运行状态(涵盖Jps ,jstat ,jinfo ,jstack ,部分Jmap功能)。

    • 在不需要重新部署服务的情况下修改业务代码。

    • 以局视角来查看系统的运行状况。

Arthas 安装

下载

curl -O https://arthas.aliyun.com/arthas-boot.jar

启动

java -jar arthas-boot.jar
启动成功后

选择监控的应用

Arthas启动成功后会打印出来当前服务器的所有java进程,然后以编号的形式排列出来,在控制台输入你想要监控的应用编号,然后回车,即可进入arthas的监控控制台,这里我选择了编号为7的应用进行监控

这样就成功附着到了该进程。接下来就可以执行各种命令来分析JVM了。

help

使用 help 命令可以看到 Arthas 的命令概览

[arthas@36934]$ help
 NAME         DESCRIPTION
 help         Display Arthas Help
 keymap       Display all the available keymap for the specified connection.
 sc           Search all the classes loaded by JVM
 sm           Search the method of classes loaded by JVM
 classloader  Show classloader info
 jad          Decompile class
 getstatic    Show the static field of a class
 monitor      Monitor method execution statistics, e.g. total/success/failure count, average rt, fail rate, etc.
 stack        Display the stack trace for the specified class and method
 thread       Display thread info, thread stack
 trace        Trace the execution time of specified method invocation.
 watch        Display the input/output parameter, return object, and thrown exception of specified method invocation
 tt           Time Tunnel
 jvm          Display the target JVM information
 perfcounter  Display the perf counter infornation.
 ognl         Execute ognl expression.
 mc           Memory compiler, compiles java files into bytecode and class files in memory.
 redefine     Redefine classes. @see Instrumentation#redefineClasses(ClassDefinition...)
 dashboard    Overview of target jvm's thread, memory, gc, vm, tomcat info.
 dump         Dump class byte array from JVM
 heapdump     Heap dump
 options      View and change various Arthas options
 cls          Clear the screen
 reset        Reset all the enhanced classes
 version      Display Arthas version
 session      Display current session information
 sysprop      Display, and change the system properties.
 sysenv       Display the system env.
 vmoption     Display, and update the vm diagnostic options.
 logger       Print logger info, and update the logger level
 history      Display command history
 cat          Concatenate and print files
 echo         write arguments to the standard output
 pwd          Return working directory name
 mbean        Display the mbean information
 grep         grep command for pipes.
 tee          tee command for pipes.
 profiler     Async Profiler. https://github.com/jvm-profiling-tools/async-profiler
 stop         Stop/Shutdown Arthas server and exit the console.

此外,还可以查看每个命令的用法举例,命令后面加 -help,例如:

[arthas@36934]$ help -help
 USAGE:
   help [-h] [cmd]

 SUMMARY:
   Display Arthas Help
 Examples:
  help
  help sc
  help sm
  help watch

 OPTIONS:
 -h, --help                                      this help
 <cmd>                                           command name
常用命令
查看系统实时运行状态(dashboard)
  • dashboard 命令可以总览 JVM 状况(默认 5 秒刷新一次):

  • 在控制台输入dashboard 回车后会看到下图对应的信息,这里主要展示了当前监控的进程信息、包括 实时的线程信息、内存分配和使用状态信息、系统环境信息。

查看应用线程信息(thread)

thread可现实应用的运行线程情况,功能和jstack类似。

 thread
  • 在控制台输入thread可显示当前应用运行的线程信息。
  • 在控制台输入thread ID 可查看某一个线程的信息。
 thread  14 

修改应用中的某个类代码并动态编译和加载类到JVM

如果需要修改正在运行中的应用程序代码就很可能需要下面几个指令来帮助你完成此动作。

jad(反编译工具)

jad 可以对类进行反编译,例如反编译上面的 Hello 类,结果如下:

  • 第一步:反编译需要修改的类(jad)

jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,通过jad可以查看到应用正在运行的代码情况,这里我们使用jad 是为了确认线上某个类的运行的代码和我预期的一致,如果不一致需要修改或者增加代码则需通过后面的指令完成。

指令:jad 类全路径名

 jad  com.jaxer.jvm.arthas.Hello
[arthas@36934]$ jad com.jaxer.jvm.arthas.Hello

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@18b4aac2
  +-sun.misc.Launcher$ExtClassLoader@14612fee

Location:
/Users/jaxer/GitHub-JiaoXR/Java-Learning/jvm-learning/target/classes/

/*
 * Decompiled with CFR.
 */
package com.jaxer.jvm.arthas;

import java.time.LocalDateTime;

public class Hello 
    public void sayHello() 
        System.out.println(LocalDateTime.now() + " hello");
    


Affect(row-cnt:1) cost in 260 ms.
  • 第二步:把修改完的类动态加载到JVM(mc 和redefine)

如果我们需要修改正在运行中的应用代码,那么我们可以先准备好已经修改好的类,然后使用redefine指令把最新的代码编译加载到JVM内存里,从而达到不停应用程序修改业务代码的目的。

  1. 编译.java文件生成.class

mc /tmp/Hello.java

  1. 加载外部的.class到 jvm。
redefine /tmp/Hello.class
redefine success, size: 1

redefine 就是热部署,通俗来讲就是「开着飞机换引擎」。比如上述代码的运行结果是每隔 5 秒打印一行代码,如下

2020-05-04T16:07:04.242 hello
2020-05-04T16:07:09.247 hello
...

我们接下来修改代码

package com.jaxer.jvm.arthas;
import java.time.LocalDateTime;
public class Hello 
 public void sayHello() 
  System.out.println(LocalDateTime.now() + " I'm hungry");
 

JVM(虚拟机参数信息)

JVM可以查看当前 JVM 的运行时信息,比如机器信息、JVM 版本、启动参数、ClassPath 等

还有类加载信息、编译信息、垃圾收集器、内存相关信息:

以及操作系统信息、死锁等:

sc & sm

sc 可以查看类加载信息:

[arthas@36934]$ sc com.jaxer.*
com.jaxer.jvm.arthas.ArthasTest
com.jaxer.jvm.arthas.Hello
Affect(row-cnt:2) cost in 36 ms.

sm 可以查看类的方法信息:

[arthas@36934]$ sm com.jaxer.jvm.arthas.ArthasTest
com.jaxer.jvm.arthas.ArthasTest <init>()V
com.jaxer.jvm.arthas.ArthasTest main([Ljava/lang/String;)V
Affect(row-cnt:2) cost in 14 ms.
其他命令介绍

详细使用参考官网:https://arthas.aliyun.com/doc/advanced-use.html

命令大全
基础命令
  • help——查看命令帮助信息
  • cat——打印文件内容,和linux里的cat命令类似
  • echo–打印参数,和linux里的echo命令类似
  • grep——匹配查找,和linux里的grep命令类似
  • tee——复制标准输入到标准输出和指定的文件,和linux里的tee命令类似
  • pwd——返回当前的工作目录,和linux命令类似
  • cls——清空当前屏幕区域
  • session——查看当前会话的信息
  • reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
  • version——输出当前目标 Java 进程所加载的 Arthas 版本号
  • history——打印命令历史
  • quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
  • stop——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
  • keymap——Arthas快捷键列表及自定义快捷键
jvm相关
  • dashboard——当前系统的实时数据面板
  • thread——查看当前 JVM 的线程堆栈信息
  • jvm——查看当前 JVM 的信息
  • sysprop——查看和修改JVM的系统属性
  • sysenv——查看JVM的环境变量
  • vmoption——查看和修改JVM里诊断相关的option
  • perfcounter——查看当前 JVM 的Perf Counter信息
  • logger——查看和修改logger
  • getstatic——查看类的静态属性
  • ognl——执行ognl表达式
  • mbean——查看 Mbean 的信息
  • heapdump——dump java heap, 类似jmap命令的heap dump功能
class/classloader相关
  • sc——查看JVM已加载的类信息
  • sm——查看已加载类的方法信息
  • jad——反编译指定已加载类的源码
  • mc——内存编译器,内存编译.java文件为.class文件
  • redefine——加载外部的.class文件,redefine到JVM里
  • dump——dump 已加载类的 byte code 到特定目录
  • classloader——查看classloader的继承树,urls,类加载信息,使用classloader去getResource
monitor/watch/trace相关

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

  • monitor——方法执行监控
  • watch——方法执行数据观测
  • trace——方法内部调用路径,并输出方法路径上的每个节点上耗时
  • stack——输出当前方法被调用的调用路径
  • tt——方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
profiler/火焰图

profiler–使用async-profiler对应用采样,生成火焰图

options

options——查看或设置Arthas全局开关

以上是关于JVM技术专题精心准备了一套JVM分析工具的锦囊「下篇」的主要内容,如果未能解决你的问题,请参考以下文章

JVM技术专题精心准备了一套JVM分析工具的锦囊「下篇」

JVM技术专题精心准备了一套JVM分析工具的锦囊「JConsole补充篇」

JVM调优工具锦囊:JDK自带工具与Arthas线上分析工具对比

UAVStack JVM监控分析工具:图形化展示采集及分析监控数据

JVM技术专题网络问题分析和故障排查规划指南「实战篇」

JVM技术专题JVM分析与调优技巧分析「原理篇」