JVM AOT 缓存
提前编译(AOT)缓存是 Java 24 通过 JEP 483 引入的一项 JVM 特性,有助于减少 Java 应用程序的启动时间和内存占用。AOT 缓存是 类数据共享(Class Data Sharing, CDS) 的自然演进。 Spring Framework 同时支持 CDS 和 AOT 缓存,如果所使用的 JVM 版本(Java 24 及以上)支持该特性,建议优先使用后者。
要使用此功能,应为应用程序的特定类路径创建一个 AOT 缓存。可以在部署的实例上创建该缓存,也可以在打包应用程序时通过一次训练运行(training run)来创建,Spring 框架为此类用例提供了钩子点(hook-point)以简化操作。一旦缓存可用,用户应通过 JVM 标志选择启用它。
| 如果您正在使用 Spring Boot,强烈建议利用其 可执行 JAR 解包支持, 该功能专为满足 AOT 缓存和 CDS 的类加载需求而设计。 |
创建缓存
AOT 缓存通常可以在应用程序退出时创建。Spring 框架提供了一种运行模式,在该模式下,一旦 ApplicationContext 刷新完成,进程便会自动退出。在此模式下,所有非延迟初始化的单例对象都已被实例化,并且已调用 InitializingBean#afterPropertiesSet 回调方法;但生命周期尚未启动,ContextRefreshedEvent 事件也尚未发布。
为了在训练运行期间创建缓存,可以指定 -Dspring.context.exit=onRefresh JVM 标志,在 ApplicationContext 刷新完成后启动并立即退出 Spring 应用程序:
-
AOT cache (Java 25+)
-
AOT cache (Java 24)
-
CDS
java -XX:AOTCacheOutput=app.aot -Dspring.context.exit=onRefresh -jar application.jar ...
# Both commands need to be run with the same classpath
java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -Dspring.context.exit=onRefresh ...
java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot ...
# To create a CDS archive, your JDK/JRE must have a base image
java -XX:ArchiveClassesAtExit=app.jsa -Dspring.context.exit=onRefresh ...
在 Java 25 及以上版本中,AOT 缓存会存储包括方法性能分析信息在内的多种内容。因此,为了充分利用这一功能,建议为已经经历过部分生产环境类似工作流程的应用程序创建 AOT 缓存,而不是使用专为仅优化应用程序启动而设计的 -Dspring.context.exit=onRefresh 标志。 |
使用缓存
一旦缓存文件创建完成,您就可以使用它来更快地启动您的应用程序:
-
AOT cache
-
CDS
# With the same classpath (or a superset) tan the training run
java -XX:AOTCache=app.aot ...
# With the same classpath (or a superset) tan the training run
java -XX:SharedArchiveFile=app.jsa ...
请注意日志和启动时间,以检查 AOT 缓存是否成功使用。
要了解缓存的有效性,可以通过添加一个额外的参数来启用类加载日志:
-Xlog:class+load:file=aot-cache.log。这将生成一个 aot-cache.log 文件,
记录每次尝试加载类及其来源的信息。从缓存中加载的类应显示“shared objects file”作为其来源,如下例所示:
[0.151s][info][class,load] org.springframework.core.env.EnvironmentCapable source: shared objects file
[0.151s][info][class,load] org.springframework.beans.factory.BeanFactory source: shared objects file
[0.151s][info][class,load] org.springframework.beans.factory.ListableBeanFactory source: shared objects file
[0.151s][info][class,load] org.springframework.beans.factory.HierarchicalBeanFactory source: shared objects file
[0.151s][info][class,load] org.springframework.context.MessageSource source: shared objects file
如果无法启用 AOT 缓存,或者您有大量类未从缓存中加载,请确保在创建和使用缓存时满足以下条件:
-
必须使用同一个 JVM。
-
类路径必须指定为 JAR 文件或 JAR 文件列表,并避免使用目录和
*通配符。 -
必须保留 JAR 文件的时间戳。
-
使用缓存时,类路径必须与创建缓存时所用的类路径完全相同,且顺序一致。 可以在末尾指定额外的 JAR 文件或目录(但这些内容不会被缓存)。