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 标志,以便在 ApplicationContext 刷新后启动并退出您的 Spring 应用程序。
-
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 文件,其中包含每次尝试加载类及其源的记录。从缓存加载的类应具有“共享对象文件”源,如以下示例所示:
[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 或目录(但不会被缓存)。