CDS

类数据共享 (CDS) 是一个 JVM 特性,可以帮助减少 Java 应用程序的启动时间和内存占用。

要使用此特性,需要为应用程序的特定类路径创建一个 CDS 归档文件。Spring Framework 提供了一个钩子点,以便于创建归档文件。一旦归档文件可用,用户应通过 JVM 标志选择使用它。

创建 CDS 归档

可以在应用程序退出时创建应用程序的 CDS 归档。Spring Framework 提供了一种操作模式,其中 ApplicationContext 刷新后进程可以自动退出。在此模式下,所有非延迟初始化的单例都已实例化,并且 InitializingBean#afterPropertiesSet 回调已被调用;但生命周期尚未开始,并且 ContextRefreshedEvent 尚未发布。

要创建归档文件,必须指定两个额外的 JVM 标志

  • -XX:ArchiveClassesAtExit=application.jsa: 在退出时创建 CDS 归档

  • -Dspring.context.exit=onRefresh: 启动 Spring 应用程序,然后按照上述描述立即退出

要创建 CDS 归档,您的 JDK/JRE 必须具有基础镜像。如果您在启动脚本中添加上述标志,可能会收到如下所示的警告

-XX:ArchiveClassesAtExit is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info.

基础 CDS 归档通常是开箱即用的,但如果需要,也可以通过发出以下命令来创建

$ java -Xshare:dump

使用归档

归档文件可用后,将 -XX:SharedArchiveFile=application.jsa 添加到您的启动脚本中以使用它,假设工作目录中存在 application.jsa 文件。

要检查 CDS 缓存是否有效,您可以使用(仅用于测试,不要在生产环境中使用)-Xshare:on,如果无法启用 CDS,该标志将打印错误消息并退出。

要了解缓存的有效性,可以通过添加一个额外的属性来启用类加载日志:-Xlog:class+load:file=cds.log。这会创建一个 cds.log 文件,其中包含每次加载类及其来源的尝试记录。从缓存加载的类应具有“共享对象文件”来源,如下例所示

[0.064s][info][class,load] org.springframework.core.env.EnvironmentCapable source: shared objects file (top)
[0.064s][info][class,load] org.springframework.beans.factory.BeanFactory source: shared objects file (top)
[0.064s][info][class,load] org.springframework.beans.factory.ListableBeanFactory source: shared objects file (top)
[0.064s][info][class,load] org.springframework.beans.factory.HierarchicalBeanFactory source: shared objects file (top)
[0.065s][info][class,load] org.springframework.context.MessageSource source: shared objects file (top)

如果无法启用 CDS 或有大量类未从缓存加载,请确保在创建和使用归档时满足以下条件

  • 必须使用完全相同的 JVM。

  • 类路径必须指定为 JAR 文件列表,避免使用目录和 * 通配符。

  • 必须保留 JAR 文件的时间戳。

  • 使用归档文件时,类路径必须与创建归档时使用的类路径相同,且顺序一致。可以在末尾指定额外的 JAR 或目录(但不会被缓存)。