Require:CDS、CRaC & GraalVM 加速 SpringBoot 启动速度

发布于:2025-02-10 ⋅ 阅读:(77) ⋅ 点赞:(0)

CDS 通过共享类数据来加速启动,CRaC 通过运行时优化来提升性能,而 GraalVM 则通过 AOT 编译来实现快速启动和高效运行。

  • CDS 基于 jar 运行。
  • CRaC 只能在 Linux 平台。

1,CDS(类数据共享)

CDS 通过在 JVM 启动时预加载常用的类数据并将它们共享在多个 JVM 实例之间来优化性能。这些类数据包括类的元数据、方法、常量池等。它是 OpenJDK(JDK 5 开始) 主线中成熟且可用于生产的技术,与 GraalVM 和 Project CRaC 相比,它更易于使用,因为它具有较少的限制和副作用。

【工作原理】

  • 生成共享类文件:在安装 JDK 时,JVM 会为标准库的类生成一个共享的类元数据文件(如 classes.jsa 或 classes.jsa 文件)。这个文件会包含 Java 标准类库的常用类(如 java.lang.String、java.util.* 等)的元数据。
  • 加载共享数据:JVM 启动时,会将这些共享数据映射到内存中,而不是每次都重新加载这些类的元数据。由于这些数据是只读的,它们可以在多个 JVM 实例之间共享,从而减少了内存占用。
  • 自定义类数据存储:JDK 10 开始,支持应用程序自定义的类数据存储(Application Class Data Sharing, AppCDS)。

【使用方式】

  • 以分解形式对应用程序执行训练运行:这将创建一个  application 目录并生成 application.jsa,只要应用程序未更新,就可以重复使用。
java -Djarmode=tools -jar my-app.jar extract --destination application

cd application

java -XX:ArchiveClassesAtExit=application.jsa -Dspring.context.exit=onRefresh -jar my-app.jar
  • 要使用缓存,需要在启动应用程序时添加一个额外的 -XX:SharedArchiveFile 参数:
java -XX:SharedArchiveFile=application.jsa -jar my-app.jar

2,CRaC(检查点协调恢复)

CRaC 是一个 OpenJDK 项目,可以“快照”正在运行的 JVM(Java 虚拟机)并将其状态(包括你的应用程序)存储到磁盘。然后,在另一个时间点,可以将 JVM 从保存的检查点恢复到内存中。这样就可以启动应用程序、预热它并创建检查点。从保存的检查点恢复到内存主要依赖于磁盘I/O,这意味着它非常快(在毫秒范围内)。从 Spring Boot3.2/Spring6.1 开始对 CRaC 的提供支持。

【工作原理】

  • 创建检查点:在应用程序运行并达到稳定状态后,可以创建一个检查点,这个检查点包含了 JVM 的状态和应用程序的数据。
  • 存储检查点:检查点数据被存储到磁盘上,以便之后可以从中恢复。
  • 恢复检查点:当需要启动应用程序时,可以直接从检查点恢复,而不是从头开始启动和预热 JVM。

CRaC 依赖于 Linux 特有的 CRIU,因此 CRaC 目前仅在Linux操作系统上支持。Windows 和 Mac 则不支持。

3,GraalVM

GraalVM 是一个高性能的运行时环境,支持多语言(如Java、JavaScript、Python、Ruby等)以及跨语言互操作。它由Oracle Labs开发,最初是作为JVM的增强项目,但后来扩展为一个通用运行时。

  • AOT编译:GraalVM的AOT编译过程中,会进行死代码消除(Dead Code Elimination),只保留实际需要的代码。这大大减少了运行时所需的资源,从而间接提升启动速度。
  • JIT编译器:传统的JVM需要加载类、初始化字节码解释器和JIT编译器,这些过程会消耗一定的时间。原生镜像在编译期已完成了这些步骤,运行时直接执行预编译的二进制文件。
  • 原生镜像:使用GraalVM的native-image工具,可以将Java应用程序静态编译为独立的原生可执行文件。这避免了运行时的字节码解释和JIT编译,直接执行原生机器码,从而显著缩短了启动时间。

GraalVM不支持反射,要做额外配置!


网站公告

今日签到

点亮在社区的每一天
去签到