手把手教你写Java-Agent

createh54个月前 (01-08)技术教程43

Java Agent是目前是各种监测调试JVM的主要技术。Eclipse,IntelliJ,Visual VM ,JConsole 等都依赖于此技术。相信你们的Java 程序部署的时候肯定也会配置各种Java Agent相关的信息。下面给大家盘一盘Java Agent!

1 Java Agent的作用

Java Agent是java.lang.instrument.Instrumentation API的一部分,Instrumentation 提供了修改字节码的机制。并且可以动态或者静态地完成。这意味着我们可以在不接触源程序代码的情况下,向程序中添加一些代码来改变程序。Java Agent有多种用途,如面向切面编程(AOP),程序分析等。AOP可以在不修改原有代码的情况下向程序提供日志记录或安全类似的功能。

我们也可以使用JavaAgent来操控字节码可以和其他的程序进行组合。在JVM的层面监听对象创建、垃圾回收,线程创建等

性能分析工具使用了大量Java Agent 在程序执行的时候分析JVM的一些参数指标。

2 Java Agent的原理

Agent类必须实现下面的方法,这个方法就是agent类的入口,类似于java 的main方法入口。

1
public static void premain(String agentArgs, Instrumentation inst)

JVM初始化之后main方法执行之前premain方法会被调用,程序中可以有多个agent。每一个agent都是按照JVM初始化的顺序进行调用。如果上述 premain方法没有找到,那么JVM会调用它的重载方法。方法如下:

1
public static void premain(String agentArgs)

JVM 启动之后,可以通过attach去调用agentmain方法,许多动态的JVM参数分析都是通过这个方法来完成的。

1
public static void agentmain(String agentArgs, Instrumentation inst)

同样的如果上述agentmain方法没有找到,那么也会执行其重载方法的版本。

1
public static void agentmain(String agentArgs)

下图为 OpenJDK11中的Agent类:

3 一个自定义Agent示例

下面我们实现一个简单的Java Agent类来体验一下Agent。

3.1 自定义Agent类

创建普通Maven工程并新建Agent启动类

1
2
3
4
5
6
7
8
9
10
11
public class JavaNorthAgent {
    //JVM启动时的agent 方法
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("premain --- agentArgs:" + agentArgs + " |inst:" + inst.toString());
    }
    //  JVM运行中的agent 方法
    public static void agentmain(String agentArgs, Instrumentation inst){
        System.out.println("agentmain --- agentArgs:" + agentArgs + " |inst:" + inst.toString());

    }
}

3.2 将Agent类打成jar包

将上述自定义Java Agent 类打包到jar包中,增加Maven build 参数如下

执行 mvn clean package命令打包后,可以看到taget目录下的jar包文件如下。

3.3 使用java命令使用指定的agent

这里我们使用java命令行启动并使用我们自定义的Java Agent类

java -javaagent:E:\javaNorth\javanorthagent\target\javanorthagent-1.0-SNAPSHOT.jar=”hello javanorth” com.javanorth.agent.Main

输出结果如下:

总结

本片简单介绍了Java Agen类的使用,并给出了一个简单的Agent代码示例。其中Visual VM ,JConsole 等工具会使用JDK自带的Agent来实现实现JVM状态分析。同样arthas 和skywalking也是使用的agent的技术来实现对JVM的监测分析。

相关文章

命令行参数

用过Unix命令行,都会感受它的强大。Unix like包括Linux发行版、macOS等命令行在大部分情况下比图形化高效太多,很多高手都在用命令行。CUI和GUI尽管专业的程序员通常用CUI, 但G...

Java中命令行调用大坑

Java中命令行调用大坑背景我司有一个查询服务接口机,QPS大概40~50,调用方式是Java调用Shell命令行的方式,核心代码如下:Process ps = Runtime.getRuntime(...

你了解JDK常用的7种命令行工具吗?

1 jps1.1 介绍jps是JDK提供的一个可以列出正在运行的Java虚拟机的进程信息的命令行工具,用来显示当前系统的java进程情况及进程id。1.2 命令格式jps [options] [hos...

CMD常用命令大全「值得收藏」

前言平常在学校上课忘记带鼠标,触摸板又有点不方便。cmd 可以解决一大半问题!通过使用窗口命令,实现无鼠标办公!或者你想在朋友面前装个 x,不妨运行一下tree总而言之,cmd 命令记一些常用的,还是...

Java设计模式——命令模式

文章目录命令模式命令模式命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者相互解耦...

看完这篇 我也会用命令行来启动程序了

最近在配置一些java相关环境的时候,本着不出错的原则,就百度了一下详细的教程,可是发现多数教程只是写了一大堆代码,但是都未能谈论到本质的东西,所以,我决定和大家来谈一下这个各大软件(语言编辑器)配置...