传统JVM和GraalVM native image在Java Agent支持上存在本质性的架构差异:
传统JVM:完整支持Java Agent的所有能力。JVM提供premain执行入口,在main函数前调用agent的premain方法。agent通过Instrumentation API注册ClassFileTransformer,在类首次加载时对字节码进行运行时动态变换。整个过程依赖JVM的类加载机制和字节码保留机制,是一个纯运行时的动态方案。
GraalVM native image:将Java应用提前编译(AOT)为本地可执行文件,不保留原始字节码,也没有传统的类加载机制。因此不能直接使用运行时的字节码变换方案。阿里巴巴贡献的方案是将agent的工作提前到编译阶段:编译时注册premain入口、先执行一次应用获取agent变换后的类并转储到磁盘、然后在编译时使用这些变换后的类。对于最终用户来说,效果与JVM上运行agent是等价的,但实现路径完全不同。目前GraalVM 24已支持premain机制,完整的agent支持将在后续版本中逐步完善。