JVM类数据共享(CDS)

什么是JVM类数据共享(CDS)?

JVM类数据共享 (Class Data Sharing, CDS)是一种 优化JVM启动速度和内存使用 的技术。它通过 在多个Java进程之间共享类元数据,避免每个进程重复加载和解析相同的类,进而提升启动速度并节省内存。

可以简单理解为:在一个大家都需要读取的文件中,JVM通过预先解析类信息,存储为一个共享的类数据文件,当多个Java进程需要时,可以从这个共享文件中读取,而不是每次都重新加载。


JVM类数据共享的原理

  1. 类元数据 :JVM在加载Java类时,需要解析 .class 文件并生成类的元数据(如类名、方法、字段等)。这些数据保存在内存中。
  2. 共享机制 :CDS通过预先将这些元数据保存到一个 共享类归档文件 中(通常是 classes.jsa 文件),并允许后续的JVM进程直接从该文件中加载类元数据,而无需再次解析和加载类文件。
  3. 减少内存占用:多个JVM实例可以共享这部分内存,避免重复加载相同的类数据。
  4. 加速启动:因为类数据是从共享归档文件中直接读取的,所以跳过了大部分的类解析过程,显著提升了JVM启动速度。

JVM类数据共享的历史

  • JDK 1.5(2004年) 首次引入了 CDS(Class Data Sharing),最初只是针对JVM自身类库进行优化。
  • JDK 10 推出了 AppCDS(应用类数据共享),允许用户类数据也能够被共享。
  • JDK 12 引入了 动态CDS归档,简化了CDS的使用流程,使其可以动态生成共享的类归档文件。

JVM类数据共享的目的

  1. 加快JVM启动时间:对于需要大量类加载的应用(如 Spring Boot),CDS可以跳过重复的类加载和解析过程,显著减少启动时间。
  2. 减少内存使用:多个JVM实例可以共享同一份类数据,节省了内存使用。
  3. 提高系统资源利用率:尤其是在多实例部署(如微服务架构)或容器化场景下,CDS优化了资源分配,避免重复加载相同的类数据。

JVM类数据共享的使用场景

  1. 微服务环境:在一个服务器上同时运行多个相似的微服务时,这些服务通常会使用相同的依赖和库。CDS通过共享类数据,减少了内存消耗。
  2. 容器化部署:如在Docker或Kubernetes中,CDS可以减少每个Java容器的内存占用并加快启动速度。
  3. 大规模集群部署:当在大规模集群上运行大量Java进程时,CDS通过共享类数据优化了系统性能和资源分配。

Spring Boot中的CDS启用情况

  1. Spring Boot 2.x 版本 :CDS默认没有启用,需要手动设置JVM参数来启动CDS。例如:

    bash 复制代码
    java -Xshare:on -XX:SharedArchiveFile=classes.jsa -jar myapp.jar
  2. Spring Boot 3.x 版本及更高:在JDK 11及以上版本中,Spring Boot应用开始更多利用JDK的CDS机制,尤其是在容器化部署中会默认启用。

通过CDS,Spring Boot应用可以显著加快启动速度,尤其是对于依赖大量类库的微服务架构和云原生环境。


启用和禁用CDS的控制

  1. 启用CDS:默认情况下可以通过以下命令启用CDS:

    bash 复制代码
    java -Xshare:on -XX:SharedArchiveFile=classes.jsa -jar myapp.jar
  2. 禁用CDS的常见方法

    • -Xshare:off:完全禁用CDS。

    • -XX:-UseSharedSpaces :这是另一种禁用CDS的方式,它完全禁用类数据共享机制。

      bash 复制代码
      java -XX:-UseSharedSpaces -jar myapp.jar
  3. -XX:SharedArchiveFile 和 -XX:-UseSharedSpaces 的区别

    • -XX:SharedArchiveFile=<path>:指定类数据共享的归档文件路径。可以自定义一个路径来存储类元数据,例如:

      bash 复制代码
      java -XX:SharedArchiveFile=/path/to/myclasses.jsa -jar myapp.jar

      这意味着共享类数据将存储在自定义的 .jsa 文件中,多个Java进程可以共享该数据。

    • -XX:-UseSharedSpaces:完全禁用类数据共享,不仅是系统类的数据共享,也包括应用类的数据共享。这种方式直接禁用了CDS的机制,不再从任何共享文件中加载类数据。


特殊情况下的禁用

在一些JDK 17及更新的版本中,某些JVM选项(如 -Xshare:none)可能不再受支持。这是因为在这些版本中,JVM对CDS的集成更深,部分功能不允许完全禁用。遇到这种情况时,你可以使用 -XX:-UseSharedSpaces 来禁用类数据共享,或者使用 -XX:SharedArchiveFile=NONE 来仅禁用应用类数据共享。


CDS在实际中的配置示例

假设你有一个 Spring Boot 项目,并且你使用了 JDK 11,你可以通过以下命令来启用CDS:

bash 复制代码
java -Xshare:on -XX:SharedArchiveFile=classes.jsa -jar my-springboot-app.jar

第一次运行时,JVM会生成共享类数据并保存到 classes.jsa 中。下次启动时,JVM会直接从该文件读取类数据,跳过类解析过程,进而加快启动速度。


总结

  • JVM类数据共享(CDS) 是JVM的一项优化技术,旨在加快启动时间和减少内存使用。它通过共享类数据,避免重复解析和加载类数据。
  • CDSJDK 1.5 开始引入,经过多次迭代改进,JDK 10 引入了 AppCDS ,进一步允许用户类共享,JDK 12 引入了动态CDS,简化了配置和使用流程。
  • 在Spring Boot应用中,特别是在 JDK 11及以上版本 中,CDS的作用尤为明显,特别适用于云原生和容器化环境。
  • 禁用CDS 可以使用 -Xshare:off-XX:-UseSharedSpaces,后者可以完全关闭类数据共享机制。
  • 在某些JDK 17版本中,-Xshare:none 可能不被支持,此时可以使用 -XX:-UseSharedSpaces 来禁用CDS。
相关推荐
xlsw_2 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹3 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭3 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫3 小时前
泛型(2)
java
超爱吃士力架3 小时前
邀请逻辑
java·linux·后端
南宫生3 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石4 小时前
12/21java基础
java
李小白664 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp4 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶4 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb