news 2025/12/26 1:52:43

JAVA25新特性:AOT优化启动性能

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JAVA25新特性:AOT优化启动性能

文章目录

  • 一、简介(实验性特性,用处不大)
    • 1、什么是AOT
    • 2、JDK24下使用AOT
    • 3、AOT优势与劣势
    • 4、用 AOT 的时候有几个注意事项
    • 5、与Springboot3.0 AOT的区别
  • 二、使用AOT(JDK25)
    • 1、基本使用
    • 2、AOT模式
      • (1)auto 模式(默认)
      • (2)record 模式
      • (3)create 模式
      • (4)on 模式
      • (5)off 模式
    • 3、JDK25使用流程
      • (1)训练阶段
      • (2)生产阶段
    • 4、配置文件管理
    • 5、应用场景
      • (1)场景一:微服务应用
      • (2)场景二:无服务器函数
      • (3)场景三:命令行工具
    • 6、高级选项
      • (1)AOTClassLinking
      • (2)环境变量配置
      • (3)文件路径占位符
      • (4)检查缓存兼容性
      • (5)查看 AOT 日志
      • (6)自动模式调试
    • 7、拓展:AOT 方法性能分析(JEP 515)

一、简介(实验性特性,用处不大)

以前Java启动慢是出了名的,特别是云原生场景下,冷启动时间直接影响用户体验。一个Spring Boot应用启动要十几秒甚至几十秒,这在Kubernetes这种需要频繁启停容器的环境里,简直就是灾难。用户请求来了,容器还在启动,等半天才能响应,体验差得不行。

后来发现大部分时间都花在类加载和链接上了,每次启动都要重新加载一遍类,解析字节码、验证类、准备类、解析符号引用,这些操作都要时间,特别是类多的时候,这时间就上去了。

从JDK24开始,这个特性引入了AOT(Ahead-of-Time)优化机制,可以把类提前加载和链接好,存到缓存里,启动时直接从缓存读取,不用再走一遍类加载流程,启动速度能提升不少。

JDK25简化了 AOT 缓存的创建过程,让优化启动性能变得更容易。以前创建 AOT 缓存得先记录应用行为,再创建缓存,两步操作;现在一个命令就搞定了,临时文件也自动管理,省事多了。

1、什么是AOT

AOT是Ahead-of-Time的缩写,意思是"提前编译"或者"提前优化"。以前Java是运行时加载类,启动的时候才去加载、验证、准备、解析,这些操作都要时间。AOT就是把这些操作提前做了,把结果存到缓存里,启动时直接用,不用再走一遍流程。

AOT类加载与链接(AOT Class Loading and Linking),它可以把类的加载和链接操作提前做好,存到AOT缓存(AOT Cache)里。启动的时候,JVM直接从缓存里读取已经加载和链接好的类,不用再重新加载,启动速度自然就上去了。

这个特性特别适合云原生场景,因为容器经常要启停,每次启动都要重新加载类,AOT缓存可以复用,启动速度能提升不少。对于那种类特别多的应用,比如Spring Boot这种框架应用,效果更明显。

AOT 的核心优势有几个:第一是启动速度快,不用等 JIT 编译,启动就能用优化后的代码;第二是预热时间短,热点代码已经编译好了,不用等运行时编译;第三是内存占用可能更小,因为不用存储那么多编译信息。

2、JDK24下使用AOT

JDK24版本的AOT使用起来非常复杂,命令行很长,咱们这里就不学习JDK24的AOT了,直接使用JDK25版本的

#!/bin/bash# 训练阶段(首次运行或更新后)if[!-f"app.aot"];thenecho"训练AOT缓存..."java -XX:AOTMode=record\-XX:AOTCacheOutput=app.aot\-XX:AOTConfigOutput=app.aotconfig\-jar microservice.jar --spring.profiles.active=trainingfi# 创建AOT缓存if[!-f"app.aot"]||["app.aotconfig"-nt"app.aot"];thenecho"创建AOT缓存..."java -XX:AOTMode=create\-XX:AOTConfig=app.aotconfig\-XX:AOTCacheOutput=app.aot\-jar microservice.jar --spring.profiles.active=createfi# 使用AOT缓存启动echo"使用AOT缓存启动..."java -XX:AOTMode=auto\-XX:AOTCache=app.aot\-jar microservice.jar

3、AOT优势与劣势

AOT 编译的代码可能不如 JIT 编译的代码优化得好,因为 JIT 可以根据运行时信息做更激进的优化。但对于启动性能要求高的应用,这个权衡通常是值得的。

AOT 可以显著缩短启动时间,因为不用等 JIT 编译,启动就能用优化后的代码。根据应用的不同,启动时间可能缩短 20% 到 50%,甚至更多。

4、用 AOT 的时候有几个注意事项

第一个是缓存兼容性。AOT 缓存跟应用、JDK 版本、操作系统、CPU 架构都有关系,不兼容的缓存不能使用。如果应用代码变了,可能需要重新创建缓存。

第二个是命令行选项兼容性。某些 JVM 选项可能跟 AOT 缓存不兼容,特别是那些会修改类的诊断选项。生产环境通常不会有这个问题,但要注意。

第三个是训练运行的代表性。训练运行应该能代表实际使用场景,这样创建的缓存才有效。如果训练运行跟实际使用差别很大,缓存的效果可能不好。

第四个是缓存文件管理。AOT 缓存文件可能比较大,要注意磁盘空间。而且缓存文件需要跟应用一起部署,部署流程可能需要调整。

5、与Springboot3.0 AOT的区别

JDK 自带的实验性特性(如jaotc 工具、-XX:AOTCache等参数),将 字节码 提前编译为 机器码库(.so/.dll),运行时由 JVM 加载,减少 JIT 实时编译开销,仍依赖 JVM 运行。

Spring Boot AOT Spring Boot 3.x 推出的官方特性,核心是 静态分析 + 预处理,生成适配原生编译的代码(消除反射 / 动态代理等动态特性),最终结合 GraalVM Native Image 编译为纯原生可执行文件,脱离 JVM 运行

对比维度Java AOT(JDK 自带)Spring Boot AOT(GraalVM 原生)
核心目标优化 JVM 运行时性能:减少热点代码的 JIT 编译耗时,小幅提升执行效率。极致优化 Spring Boot 应用的启动速度、内存占用、部署体积,适配原生编译。
运行依赖完全依赖 JVM(必须安装 JDK/JRE),机器码库仅作为 JVM 的“加速补丁”。无任何 JVM 依赖,编译为纯原生二进制文件(Linux/macOS/Windows 可执行文件)。
对动态特性的处理弱支持:无法处理反射、动态代理、类路径扫描等动态逻辑,需手动配置,对 Spring Boot 几乎无效。强支持:Spring Boot 提前做 AOT 预处理(如生成反射配置、静态代理类、移除动态扫描),自动适配 GraalVM 的静态编译规则。
优化效果启动速度:仅小幅提升(~10-20%),Spring Boot 启动的核心开销(Bean 初始化)无改善;
内存占用:基本无变化。
启动速度:从“秒级”降至“毫秒级”(典型 Spring Boot 原生应用启动 < 100ms);
内存占用:比 JVM 运行减少 50%+。
技术层级JVM 运行时优化(底层),不改变应用的运行模式(仍在 JVM 内)。应用构建层面的重构(上层),彻底改变运行模式(原生二进制)。
使用方式运行时加 JVM 参数(如-XX:AOTCacheOutput)或提前用jaotc编译类库,无需修改应用代码。构建时启用 AOT 预处理(Maven/Gradle 插件),需少量适配(如避免未声明的反射),最终编译为原生文件。
官方支持度JDK 实验性特性(自 JDK 9 引入至今未转正),未来可能被移除,无生产级保障。Spring Boot 3.x 官方主推特性,持续迭代优化,提供完整的生产级文档和兼容方案。
对 Spring Boot 的适配几乎无适配:Spring Boot 重度依赖反射/动态代理,Java AOT 无法提前编译这些逻辑,优化收益趋近于 0。深度适配:Spring Boot 自动做 AOT 转换(如@AotProcessed注解、生成静态 Bean 定义),兼容 99% 的 Spring 核心功能。

二、使用AOT(JDK25)

1、基本使用

主要是用-XX:AOTCacheOutput=<file>这个选项,一个命令就能完成记录和创建两个步骤。

# JDK25新的简化方式:一个命令搞定记录和创建# 这个命令会执行训练运行,记录应用行为,然后自动创建 AOT 缓存文件 app.aot。临时配置文件会自动管理,不用手动处理了。java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App# JDK24 得这样用,分两步:# 第一步:记录阶段,生成配置文件#java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconfig -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App# 第二步:创建阶段,根据配置文件创建缓存#java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconfig -XX:AOTCacheOutput=app.aot

2、AOT模式

(1)auto 模式(默认)

auto 模式是默认模式,会自动选择合适的 AOT 模式。如果指定了-XX:AOTCacheOutput,就自动切换到 record 模式;如果能加载 AOT 缓存,就自动切换到 on 模式;否则就切换到 off 模式。

# 不指定任何 AOT 选项,默认是 auto 模式java -cp app.jar com.example.App# 如果指定了 AOTCacheOutput,自动切换到 record 模式java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App

(2)record 模式

record 模式是训练阶段,运行应用记录行为,生成配置文件。必须指定-XX:AOTConfiguration 或 -XX:AOTCacheOutput

# record 模式:记录应用行为java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconfig -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App

如果只指定了-XX:AOTCacheOutput,JVM 会自动生成临时配置文件,不用手动指定。

(3)create 模式

create 模式是创建阶段,根据配置文件创建 AOT 缓存。必须指定-XX:AOTConfiguration

# create 模式:根据配置文件创建缓存java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconfig -XX:AOTCacheOutput=app.aot

注意 create 模式不会执行应用,只是创建缓存。

(4)on 模式

on 模式是生产阶段,使用 AOT 缓存运行应用。如果缓存加载失败,JVM 会打印错误并退出。

# on 模式:使用 AOT 缓存运行应用java -XX:AOTMode=on -XX:AOTCache=app.aot -cp app.jar com.example.App

(5)off 模式

off 模式是禁用 AOT,不使用 AOT 缓存。

# off 模式:禁用 AOTjava -XX:AOTMode=off -cp app.jar com.example.App

3、JDK25使用流程

JDK25,有了 JEP 514,使用 AOT 的流程变得简单多了。主要分两个阶段:训练阶段和生产阶段。

(1)训练阶段

训练阶段就是创建 AOT 缓存的过程。现在一个命令就搞定了:

# 训练阶段:运行应用并创建 AOT 缓存java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App# 注意,如果是一个可执行jar包,比如springboot的包,这样执行即可:# 核心命令(解锁实验性参数 + 指定 AOT 缓存输出 + 用 jar 方式启动)java -XX:+UnlockExperimentalVMOptions -XX:AOTCacheOutput=app.aot -jar app.jar

这个命令会:
1、运行应用,记录应用行为
2、自动生成临时配置文件(如果没指定 -XX:AOTConfiguration)
3、自动创建 AOT 缓存文件 app.aot
4、自动清理临时文件
不用手动管理临时文件了,省事多了。

(2)生产阶段

生产阶段就是使用 AOT 缓存运行应用。可以用 auto 模式(默认),自动加载缓存:

# 生产阶段:使用 AOT 缓存运行应用(auto 模式)java -XX:AOTCache=app.aot -cp app.jar com.example.App# 注意,如果是一个可执行jar包,比如springboot的包,这样执行即可:java -XX:AOTCache=app.aot -jar demo-0.0.1-SNAPSHOT.jar

或者用 on 模式,强制使用缓存:

# 生产阶段:强制使用 AOT 缓存(on 模式)java -XX:AOTMode=on -XX:AOTCache=app.aot -cp app.jar com.example.App# 注意,如果是一个可执行jar包,比如springboot的包,这样执行即可:java -XX:AOTMode=on -XX:AOTCache=app.aot -jar demo-0.0.1-SNAPSHOT.jar

如果缓存加载失败,auto 模式会继续运行(不用缓存),on 模式会退出(fail-fast)。

4、配置文件管理

虽然 JEP 514 简化了临时文件管理,但有时候还是需要手动指定配置文件,特别是想复用配置文件的时候。

手动指定配置文件
如果想手动指定配置文件,可以用 -XX:AOTConfiguration 选项:

# 手动指定配置文件java -XX:AOTCacheOutput=app.aot -XX:AOTConfiguration=app.aotconfig -cp app.jar com.example.App

这样配置文件会保存到app.aotconfig,可以后续复用。

使用配置文件创建缓存
如果已经有了配置文件,可以用 create 模式创建缓存:

# 使用已有配置文件创建缓存java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconfig -XX:AOTCacheOutput=app.aot

这在需要多次创建缓存的时候很有用,不用每次都运行应用。

5、应用场景

(1)场景一:微服务应用

微服务应用启动频繁,启动性能直接影响用户体验。用 AOT 可以显著提升启动速度。

# 训练阶段:创建 AOT 缓存java -XX:AOTCacheOutput=service.aot -jar service.jar# 生产阶段:使用 AOT 缓存运行java -XX:AOTCache=service.aot -jar service.jar

(2)场景二:无服务器函数

无服务器函数每次调用都可能启动新的实例,启动性能特别重要。用 AOT 可以缩短冷启动时间。

# 训练阶段:创建 AOT 缓存java -XX:AOTCacheOutput=function.aot -cp function.jar com.example.Function# 生产阶段:使用 AOT 缓存运行java -XX:AOTCache=function.aot -cp function.jar com.example.Function

(3)场景三:命令行工具

命令行工具启动频繁,用 AOT 可以提升响应速度。

# 训练阶段:创建 AOT 缓存java -XX:AOTCacheOutput=tool.aot -cp tool.jar com.example.Tool --help# 生产阶段:使用 AOT 缓存运行java -XX:AOTCache=tool.aot -cp tool.jar com.example.Tool

6、高级选项

除了基本的选项,AOT 还有一些高级选项,可以更精细地控制行为。

(1)AOTClassLinking

-XX:+AOTClassLinking选项可以启用更高级的优化,比如提前解析invokedynamic指令,进一步提升启动和预热性能。

# 启用 AOTClassLinkingjava -XX:AOTCacheOutput=app.aot -XX:+AOTClassLinking -cp app.jar com.example.App

注意,用 AOTClassLinking 创建的缓存可能跟某些生产环境的命令行参数不兼容,用的时候要注意。

(2)环境变量配置

可以用JDK_AOT_VM_OPTIONS环境变量给第二个 JVM 进程传递额外的选项(在 record 模式下):

# 设置环境变量,给第二个 JVM 进程传递选项exportJDK_AOT_VM_OPTIONS="-Xmx2g -XX:+UseG1GC"# 运行训练java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App

(3)文件路径占位符

可以用占位符在文件路径中包含进程 ID 或启动时间戳:

# 使用进程 ID 占位符java -XX:AOTConfiguration=foo%p.aotconfig -XX:AOTCacheOutput=foo%p.aot -cp app.jar com.example.App# 使用时间戳占位符java -XX:AOTConfiguration=foo%t.aotconfig -XX:AOTCacheOutput=foo%t.aot -cp app.jar com.example.App

(4)检查缓存兼容性

-XX:AOTMode=on可以检查命令行选项是否兼容 AOT 缓存:

# 检查兼容性(fail-fast 模式)java -XX:AOTMode=on -XX:AOTCache=app.aot -cp app.jar com.example.App

如果缓存加载失败,JVM 会立即退出,这样可以快速发现问题。

(5)查看 AOT 日志

-Xlog:aot可以查看 AOT 相关的日志:

# 查看 AOT 日志java -XX:AOTMode=auto -XX:AOTCache=app.aot -Xlog:aot -cp app.jar com.example.App

这样可以了解缓存是否被使用,以及使用的情况。

(6)自动模式调试

如果不想用 fail-fast 模式,可以用 auto 模式配合日志:

# 自动模式 + 日志,查看缓存使用情况java -XX:AOTMode=auto -XX:AOTCache=app.aot -Xlog:aot -cp app.jar com.example.App

这样即使缓存加载失败,应用也能继续运行,同时能看到日志信息。

7、拓展:AOT 方法性能分析(JEP 515)

JDK25使用AOT时,会自动自动收集性能分析数据。

自动分析if分支预测、方法调用频率、循环执行数据、类型信息数据等。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/26 1:50:10

Dify如何平衡灵活性与易用性?产品设计理念解读

Dify如何平衡灵活性与易用性&#xff1f;产品设计理念解读 在AI技术快速渗透各行各业的今天&#xff0c;大语言模型&#xff08;LLM&#xff09;早已不再是实验室里的“黑科技”&#xff0c;而是企业构建智能客服、自动化内容生成、知识问答系统的核心引擎。然而&#xff0c;一…

作者头像 李华
网站建设 2025/12/26 1:46:01

Java Web 教学资源共享平台系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

摘要 随着信息技术的快速发展&#xff0c;教育资源共享平台成为高校信息化建设的重要组成部分。传统教学资源管理方式存在资源分散、共享效率低、更新不及时等问题&#xff0c;难以满足师生多样化需求。基于此&#xff0c;设计并实现一个高效、便捷的教学资源共享平台具有重要的…

作者头像 李华
网站建设 2025/12/26 1:45:20

Proteus 8 Professional电子电路设计超详细版教程

从零开始掌握Proteus 8&#xff1a;电子电路设计与仿真的全能实战指南 你有没有过这样的经历&#xff1f; 花了一周时间画好原理图、打样PCB、焊完板子&#xff0c;结果上电一测——芯片发热、信号异常、单片机不启动。更糟的是&#xff0c;问题出在哪&#xff1f;是电源没接稳…

作者头像 李华
网站建设 2025/12/26 1:43:37

Altium Designer中原理图模板设置手把手教程

Altium Designer中原理图模板设置实战全解&#xff1a;从零搭建高效设计环境你有没有遇到过这样的场景&#xff1f;新项目启动&#xff0c;打开Altium Designer&#xff0c;第一件事不是画电路&#xff0c;而是花半小时手动设置图纸大小、调整栅格、复制粘贴标题栏、填写公司信…

作者头像 李华
网站建设 2025/12/26 1:43:26

Dify平台能否用于舆情监控?新闻聚合与情感分析实践

Dify平台能否用于舆情监控&#xff1f;新闻聚合与情感分析实践 在信息爆炸的今天&#xff0c;一条负面新闻可能在几小时内发酵成全网热议事件。某知名品牌曾因产品缺陷被曝光后24小时内股价下跌8%&#xff0c;而危机爆发前竟无任何系统预警——这正是传统舆情监控系统的典型短板…

作者头像 李华
网站建设 2025/12/26 1:38:40

为工业4.0赋能:Vivado注册2035系统级设计全面讲解

为工业4.0构建可持续FPGA开发体系&#xff1a;从“Vivado注册2035”谈起你有没有遇到过这样的场景&#xff1f;一个运行了八年的产线控制系统&#xff0c;突然因为开发工具许可证到期而无法重新编译固件&#xff1b;或者团队接手老项目时发现&#xff0c;连原始设计用的是哪个版…

作者头像 李华