Skip to content

Latest commit

 

History

History
103 lines (58 loc) · 3.52 KB

javaagent.md

File metadata and controls

103 lines (58 loc) · 3.52 KB

Load-Time

  • 在Manifest部分,需要定义Premain-Class属性。

    在Agent Class部分,需要定义premain方法。下面是premain的两种写法:

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

    在运行的时候,需要配置-javaagent选项加载Agent Jar:

    java -cp ./target/classes/ -javaagent:./target/TheAgent.jar sample.Program
    

    在运行的过程当中,先执行Agent Class的premain方法,再执行Application的main方法。

Dynamic

  • 在Manifest部分,需要定义Agent-Class属性。

    在Agent Class部分,需要定义agentmain方法。下面是agentmain的两种写法:

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

    在运行的时候,需要使用Attach机制加载Agent Jar。

    在运行的过程当中,一般Application的main方法已经开始执行,而Agent Class的agentmain方法后执行。

  • 第一点,Agent Jar的三个组成部分:Manifest、Agent Class和ClassFileTransformer。

  • 第二点,对Load-Time Instrumentation和Dynamic Instrumentation有一个初步的理解。

    • Load-Time Instrumentation: Premain-Class —> premain() —> -javaagent
    • Dynamic Instrumentation: Agent-Class —> agentmain() —> Attach
  • 第一点,Attach API位于

    com.sun.tools.attach
    

    包:

    • 在Java 8版本,com.sun.tools.attach包位于JDK_HOME/lib/tools.jar文件。
    • 在Java 9版本之后,com.sun.tools.attach包位于jdk.attach模块(JDK_HOME/jmods/jdk.attach.jmod文件)。
  • 第二点,在com.sun.tools.attach包当中,重要的类有三个:VirtualMachine(核心功能)、VirtualMachineDescriptor(三个属性)和AttachProvider(底层实现)。

  • 第三点,使用

    VirtualMachine
    

    类分成三步:

    • 第一步,与target VM建立连接,获得一个VirtualMachine对象。
    • 第二步,使用VirtualMachine对象,可以将Agent Jar加载到target VM上,也可以从target VM读取一些属性信息。
    • 第三步,与target VM断开连接。

Load-Time VS. Dynamic Agent

1. 虚拟机数量

Load-Time Instrumentation只涉及到一个虚拟机

Dynamic Instrumentation涉及到两个虚拟机

2. 时机不同

在进行Load-Time Instrumentation时,会执行Agent Jar当中的premain()方法;premain()方法是先于main()方法执行,此时Application当中使用的大多数类还没有被加载

在进行Dynamic Instrumentation时,会执行Agent Jar当中的agentmain()方法;而agentmain()方法是往往是在main()方法之后执行,此时Application当中使用的大多数类已经被加载

3. 能力不同

Load-Time Instrumentation可以做很多事情:添加和删除字段、添加和删除方法等。

Dynamic Instrumentation做的事情比较有限,大多集中在对于方法体的修改。

4. 线程不同

Load-Time Instrumentation是运行在main线程里

Dynamic Instrumentation是运行在Attach Listener线程里

5. Exception处理

当Load-Time Instrumentation时,出现异常,会报告错误信息,并且停止执行,退出虚拟机。

当Dynamic Instrumentation时,出现异常,会报告错误信息,但是不会停止虚拟机,而是继续执行。