CnOps 社区
首页开源项目实践文章视频课程常见问答开发者工具
导航菜单
首页开源项目实践文章视频课程常见问答开发者工具

CnOps 社区

愿景

CnOps 社区是一个以"智能运维与可观测"为核心的开放、包容、分享的技术社区,旨在聚集运维专家、开发者和爱好者,共同探讨、学习和分享可观测最佳实践与最新技术,与众多技术社区合作互动,共同探讨交叉领域的技术挑战,推动可观测领域的创新与进步。

内容社区

  • 实践文章
  • 视频课程
  • 开源项目
  • 常见问答
  • 开发者工具

友情链接

  • Prometheus
  • Grafana Lab
  • OpenTelemetry
  • LoongCollector

关注我们

阿里云云原生公众号阿里云云原生
阿里云可观测公众号阿里云可观测

Copyright © 2026 CnOps 社区. All rights reserved.

首页实践文章GraalVM 24正式发布阿里巴巴贡献重要特性 —— 支持Java Agent插桩

GraalVM 24正式发布阿里巴巴贡献重要特性 —— 支持Java Agent插桩

#监控#指标#数据采集#api#Java#阿里云

agenticOps | 2026-05-23

2025年3月18日Oracle双箭齐发,正式发布了JDK 24和GraalVM 24,带来了众多新特性。

JDK 24在性能和安全性方面均有改进(特性列表),其中较大的一处改动是在JDK中用新的Class-File API取代了ASM接口,使Java agent在动态修改Java字节码时更加方便快捷。与之相呼应,GraalVM 24在提升运行时性能、降低native image制品大小、提升调试体验等各方面的改进和提升之外(特性列表),也迈出了在native image中静态化支持Java agent插桩的第一步。这就是在发布中提到的Premain Support for Java Agents新特性,即支持Java agent的premain机制。

这是由阿里巴巴贡献到GraalVM社区的新特性。阿里巴巴是GraalVM全球顾问委员会的唯一中国代表,阿里云程序语言与编译器团队和可观测团队合作实现了GraalVM应用的无侵入可观测能力,并在ARMS平台上线了该功能。目前在GraalVM24中发布的是支持Java agent的第一步,其余能力将在GraalVM的后续版本中陆续发布。

实现原理

Java agent是一种动态修改Java运行时代码的技术,无需应用程序修改任何内容,由Java agent在运行时修改实际要执行的内容,广泛使用于Java应用监控领域。Java应用在上线后一般都会接入以Java agent为核心的可观测平台,监测运行时行为。

Java agent的实现有两点基础,GraalVM都不具备:

  1. JVM的premain机制。如果希望应用在运行时自始至终用到的都是经过变换的类,那么就需要在应用正式开始前就把修改类的需求告诉JVM,然后在首次加载类时进行修改。Java规范要求Java agent必须要提供名为premain的函数,在里面实现注册变换、选项解析、上下文环境初始化等工作。JVM则提供了相应的执行入口,保证在执行主函数之前会调用各个agent的premain函数。但是在GraalVM的运行时中并没有设计过该机制,所以agent就不会有被调用的机会。
  2. 对Java的字节码进行变换。修改字节码,改变目标的运行时行为。在JDK24之前基于ASM接口修改,在JDK24之后基于Class-File接口。GraalVM将Java应用编译为native应用后不再保留字节码,因此失去了可以修改的目标,而且native应用本身也不支持动态修改。

GraalVM因为不能支持Java agent而失去了可观测能力,这一功能缺失阻碍了很多用户适配GraalVM。

我们在GraalVM上实现对Java agent的支持就是解决了以上两个问题。

首先,在GraalVM的编译时识别用户的premain函数,将它们加入编译队列,然后注册到运行时的premain入口。这样编译制品native image就会在运行时成功找到premain函数,然后执行其中的业务逻辑。这次在GraalVM24中发布的就是这部分功能。

其次,将Java agent的类转换动作从运行时提前到编译时。因为基于premain的agent即使在JVM中,也是在首次加载目标类的时候对其进行变换,然后将变换好的结果返回给类加载器的。使用者首次见到的类就是变换后的,那么对于使用者来说,编译时变换和运行时变换就是等价的。所以我们只要将agent转换好的类编译进native image就可以了。那么问题就转换为如何在编译时获得agent变换后的类。

关于这个问题,我们的实现思路是先让挂载agent的Java应用执行一次,在此过程中把经过agent转换的类转储到磁盘,然后在编译时使用这些类。

通过 ARMS 对 GraalVM 应用进行观测

目前阿里云应用实时监控服务平台(ARMS https://www.aliyun.com/product/arms) 已经基于上述方案,完成了对Java Agent的GraalVM静态编译能力支持。具体使用ARMS对GraalVM应用进行可观测的方法请参考ARMS官方文档:https://help.aliyun.com/zh/arms/application-monitoring/use-cases/connect-graalvm-applications-to-arms

当完成静态编译后,相关可执行 Native Image 文件中就包含了 ARMS 可观测 Java Agent 的代码。执行按照正常 GraalVM 应用部署运行方式进行运行即可,以下是其在 ARMS 控制台上的部分可观测数据采集效果:

GraalVM应用指标数据采集效果

GraalVM应用调用链数据采集效果

如下图是一个通过 Spring Schedule 发起定时任务调用 Restful 接口,然后通过 HttpClient 对外进行调用的示例:

性能效果

我们基于上述方案,也对 GraalVM 应用在启动速度和运行时内存占用进行了一些测试验证,发现 Java 应用基于 GraalVM 静态编译后,不仅可以正常使用开箱即用的可观测能力,运行时内存占用和启动延时仍然有巨大的优化效果(以下测试在32 vCPU/64 GiB/5 Mbps环境中完成)。

总结

GraaLVM24正式发布了由阿里巴巴贡献的premain机制,拉开了对Java agent的静态编译支持大幕。

尽管GraalVM社区对无侵入式可观测的支持还处于早期阶段,但阿里云ARMS平台已经上线了完整的静态编译可观测能力支持。欢迎对上述相关产品能力和技术方案感兴趣的读者试用ARMS,希望获取相关资料和做进一步交流探讨的读者请加钉钉群: 80805000690。

文章大纲