写在前面

本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构和文献引用请见100个问题搞定Java虚拟机

解答

Java Agent 概述

Java Agent 本质上是 JDK 提供的一个工具。

在 JDK1.5 之后,可以使用 Java Agent 技术构建一个独立于应用程序的代理程序(即Agent)。

可以用来协助监测、运行甚至替换其他JVM上的程序。使用它可以实现虚拟机级别的 AOP 功能,比如字节码注入。

Java Agent 的作用

我们可以通过 Java Agent 的类加载拦截功能,修改某个类所对应的字节码二进制数组,并利用这个修改过后的二进制数组完成接下来的类加载。

JavaAgent 是运行在 main 方法之前的拦截器,它内定的方法名叫 premain ,也就是说先执行 premain 方法然后再执行 main 方法。

我们之前专栏中提到的 Arthas 本质上就是通过 Java Agent 实现的。

关于 Arthas 请参考我的另一篇博客——震惊!原来 Arthas 入门这么简单!5 分钟就搞定了!

Java Agent 的问题

基于字节码注入的 profiler,可以统计程序运行过程中某些行为的出现次数。

如果需要收集 Java 核心类库的数据,那么我们需要小心避免无限递归调用。另外,我们还需通过自定义类加载器来解决命名空间的问题。

由于字节码注入会产生观察者效应,因此基于该技术的 profiler 所收集到的数据并不能反映程序的真实运行状态。它所反映的是程序在被注入的情况下的执行状态。

Java Agent 的底层实现原理

Java Agent 本质上是通过 c agent 来实现的。

C Agent 是一个事件驱动的工具实现接口,通常我们会在 C Agent 加载后的入口方案 Agent_OnLoad 处注册各个事件的钩子方法。

当Java虚拟机触发了这些事件时,便会调用对应的钩子方法。

上一篇 下一篇