一、Arthas简介

        Arthas(阿尔萨斯)是Alibaba开源的Java诊断工具。支持Linux/Mac/Windows

        1、下载地址: https://github.com/alibaba/arthas/releases

        

阿尔萨斯实时监控线程cpu占用 阿尔萨斯 监控_阿尔萨斯实时监控线程cpu占用

        2、arthas-bin解压之后的目录结构

阿尔萨斯实时监控线程cpu占用 阿尔萨斯 监控_jvm_02

二、启动Arthas监测应用程序

        1、用as.sh启动

        ./as.sh

        2、用arthas-boot启动

        java -jar arthas-boot.jar

        3、选择要监控的进程pid,启动成功之后进入arthas命令行交互模式

阿尔萨斯实时监控线程cpu占用 阿尔萨斯 监控_jvm_03

三、Arthas常用命令

        1、被监控的测试类

package com.yu.visualVM;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class BTraceTest {
	
	private static String yuTest="wj";
    private int c=10;
	
	public int add(int a, int b) {
		return a + b;
	}

	public static void main(String[] args) throws Exception {
		BTraceTest traceTest = new BTraceTest();
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		for (int i = 0; i < 10; i++) {
			reader.readLine();
			int a = (int) Math.round(Math.random() * 1000);
			int b = (int) Math.round(Math.random() * 1000);
			System.out.println(traceTest.add(a, b));
		}
	}
}

 

 

        2、jad:反编译

反编译整个类

jad com.yu.visualVM.BTraceTest

 

反编译类中的方法

jad com.yu.visualVM.BTraceTest add

阿尔萨斯实时监控线程cpu占用 阿尔萨斯 监控_阿尔萨斯实时监控线程cpu占用_04

        3、watch:观察指定方法的调用情况。能观察的范围为:返回值抛出异常入参

观察方法入参、this对象和返回值(观察表达式,默认值是{params, target, returnObj}

watch com.yu.visualVM.BTraceTest  add

-x 2

 观察方法入参

watch com.yu.visualVM.BTraceTest add

"{params,returnObj}" -x 2 -b

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

watch com.yu.visualVM.BTraceTest  add

"{params,target,returnObj}" -x 2 -b -s -n 2

观察入参第一个参数且参数值>101

watch com.yu.visualVM.BTraceTest  add

"{params[0],target}""params[0]>101"

观察当前对象中的属性

watch com.yu.visualVM.BTraceTest  add

"target.yuTest"

观察方法入参:watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b

阿尔萨斯实时监控线程cpu占用 阿尔萨斯 监控_visualvm_05

 观察入参第一个参数且参数值>101:

阿尔萨斯实时监控线程cpu占用 阿尔萨斯 监控_visualvm_06

四、Arthas使用场景

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  5. 是否有一个全局视角来查看系统的运行状况?
  6. 有什么办法可以监控到JVM的实时运行状态?
  7. 怎么快速定位应用的热点,生成火焰图?
  8. 怎样直接从JVM内查找某个类的实例?

五、Arthas运行原理

        1、 实现java.lang.instrument

        这个类提供检测Java编程语言代码所需的服务。插装是在方法中添加字节码,以收集工具所使用的数据。由于这些更改纯粹是附加的,所以这些工具不会修改应用程序的状态或行为。此类良性工具的示例包括监视代理、分析程序、覆盖率分析程序和事件日志记录程序。

有两种方法可以获得Instrumentation接口的实例:

        当JVM以指示代理类的方式启动时。在这种情况下,将Instrumentation实例传递给代理类的main方法。

        当JVM提供了在JVM启动后某个时间启动代理的机制时。在这种情况下,将Instrumentation实例传递给代理代码的agentmain方法。

        2、实现ASM

        ASM是一个Java字节码操作框架,用来动态生成class或者增强class,cglib的底层就是它,arthas也是通过它实现对class的增强的。

        3、实现接口JVMTI

What is the JVM Tool Interface?

       JVM TI 是开发和监控工具使用的编程接口。它提供了一种检查状态和控制运行在JavaTM虚拟机(VM)中的应用程序执行的方法。

        JVM TI 旨在为所有需要访问VM状态的工具提供VM接口,包括但不限于:概要分析、调试、监视、线程分析和覆盖率分析工具。

        JVM TI 是一个双向接口。JVM TI的客户机(以下称为代理)可以通过事件通知有趣的事件。JVM TI可以通过许多函数查询和控制应用程序,这些函数可以响应事件,也可以独立于事件。

代理程序与执行所检查应用程序的虚拟机在同一进程中运行,并直接与之通信。这种通信是通过本机接口(JVM TI)进行的。本机进程内接口允许最大限度的控制,对工具的入侵最小。通常,代理是相对紧凑的。它们可以由一个独立的进程控制,该进程实现了工具的大部分功能,而不会干扰目标应用程序的正常执行。