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 或目录(但不会被缓存)。