JVM AOT 缓存
预编译(AOT)缓存是 Java 24 中通过 JEP 483 引入的一项 JVM 功能,可以帮助缩短 Java 应用程序的启动时间和减少内存占用。AOT 缓存是 类数据共享 (CDS) 的自然演进。Spring Framework 支持 CDS 和 AOT 缓存,建议您在所使用的 JVM 版本(Java 24+)中优先使用后者。 要使用此功能,需要为应用程序的特定类路径创建 AOT 缓存。可以在已部署的实例上创建此缓存,或者在训练运行期间(例如在打包应用程序时)创建,这得益于 Spring Framework 提供的钩子点,可简化此类用例。一旦缓存可用,用户应通过 JVM 标志选择使用它。
|
如果您正在使用 Spring Boot,强烈建议利用其 可执行 JAR 解包支持, 该支持旨在满足 AOT 缓存和 CDS 的类加载要求。 |
创建缓存
AOT 缓存通常可以在应用程序退出时创建。Spring Framework 提供了一种操作模式,在该模式下,一旦 ApplicationContext 刷新,进程就可以自动退出。在此模式下,所有非延迟初始化的单例都已实例化,并且 InitializingBean#afterPropertiesSet 回调已调用;但生命周期尚未开始,并且 ContextRefreshedEvent 尚未发布。
要在训练运行期间创建缓存,可以指定 -Dspring.context.exit=onRefresh JVM 标志来启动您的 Spring 应用程序,并在 ApplicationContext 刷新后退出:
-
AOT 缓存
-
CDS
# 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 ...
使用缓存
缓存文件创建后,您可以使用它来更快地启动应用程序:
-
AOT 缓存
-
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 或目录(但不会被缓存)。