Skip to content

什么是 CDS/AppCDS 与 AOT 类加载?对启动速度有什么帮助? ​

  • 标签:Java、新特性

🏛 业务架构师 ​

CDS/AppCDS 与 AOT 类加载对启动速度的帮助:

机制分层讲:

  1. CDS(Class Data Sharing):JDK 把"类加载后解析好的元数据"打成共享归档文件(默认 CDS archive 由 JDK 自带),启动时直接内存映射归档——跳过类数据的读取、解析步骤。基础 CDS 只覆盖 JDK 核心类,启动提速约 10%~15%;
  2. AppCDS(应用级 CDS):把你自己应用的类也做进归档(java -Xshare:dump -XX:SharedArchiveFile=app.jsa,或 JDK 19+ 的默认自动生成 -XX:+AutoCreateSharedArchive)——应用类才是启动加载的大头,企业 Spring 应用实测再省 20%~40% 启动时间;
  3. Spring Boot 3 的 AOT:构建时把 Bean 定义、反射元数据提前生成为静态代码——启动时不再跑 ASM 字节码扫描、条件装配推演,类加载与初始化的总量本身大幅减少;配合 CDS(Spring Boot 支持 extract + CDS 训练运行)叠加收益;
  4. CRaC(Coordinated Restore at Checkpoint,另路线):运行预热后的进程直接"拍快照",启动=恢复快照——百毫秒级回到满血状态,Azul Spring Boot 支持已成熟。

业务价值与选型:启动时间在两处值钱——弹性扩容(流量洪峰来时扩容速度=每实例启动时间)与 Serverless(冷启动即用户等待)。我的建议组合:常规 K8s 服务用 AppCDS+Spring AOT(改造小、提速 30%+);极致冷启动需求上 Native Image 或 CRaC。一条实施心得:先量化(启动耗时分解:类加载 vs Bean 初始化 vs JIT 预热)再选手段——别拿着 Native 的锤子去修一个只需要 AppCDS 的螺丝。

🏗 系统架构师 ​

CDS/AppCDS 与 AOT 类加载 = 用"构建时/首次运行的缓存"换启动速度——JVM 启动优化的三层方案:

  • CDS(Class Data Sharing,JDK 5+ 基础):JDK 类的元数据(类结构、常量池预处理结果)打成共享归档文件,多 JVM 进程内存映射共享同一份只读元数据——单进程启动快(跳过解析),多容器/多进程部署还有内存共享红利(同宿主机 N 个 JVM 共享一份 JDK 类元数据,容器密度场景的真实收益);
  • AppCDS(应用类也纳入):-XX:SharedClassListFile + -Xshare:dump 把应用与依赖的类也做进归档——Spring 这类"类海应用"启动提速 20~40%;
  • 动态归档(JDK 13+):-XX:ArchiveClassesAtExit 应用首次运行时自动"学习"加载过的类生成归档——免手工维护类列表(Spring Boot 3 已自动生成 CDS 归档);
  • AOT 类加载(JDK 24/25 的 AOT Cache):比 CDS 更进一步——不只元数据,连方法的部分编译结果(AOT 代码)也缓存(java -XX:AOTCache 生成,启动时直接映射执行)——启动提速到接近 native image 的一部分收益(官方目标:接近一半的 native 提速)但保留 JIT 峰值能力——"第三条路":毫秒~百毫秒级启动 + 完整 JIT 性能。

架构师选型谱系(启动优化的档位):

  • 轻量优化:CDS/AppCDS(零行为风险,容器密度红利);
  • 进一步:AOT Cache(JDK 24+,JVM 模式快速启动);
  • 极致:GraalVM Native(毫秒启动 + 低内存,换峰值性能与动态性);
  • 另一路:CRaC 检查点(启动时恢复运行态快照)——Serverless 场景竞争方案。

注意:归档与 JDK 版本/类路径强绑定(变更即失效需重建);CI 流水线把归档生成纳入构建产物。

💻 全栈开发专家 ​

CDS(Class Data Sharing)/AppCDS:把类加载解析的结果(类元数据)在构建期打包成归档文件,JVM 启动时内存映射直接使用——跳过「读 class 文件 → 解析验证」的重复劳动,多进程还能共享同一份只读归档(物理内存一份)。

AOT 类加载(JDK 24,JEP 483 AOT Cache;25 增强启动优化):更进一步——把热点方法预热后的机器码(C1 编译产物)在训练运行时 dump 成 AOT 归档,下次启动直接加载编译后代码,连 JIT 预热都省了。

对启动速度的帮助(实测数量级):

bash
# AppCDS 三步(JDK 13+ 流程已简化)
java -XX:DumpLoadedClassList=app.classlist -jar app.jar   # 1. 记录类清单
java -Xshare:dump -XX:SharedClassListFile=app.classlist \
     -XX:SharedArchiveFile=app.jsa -cp app.jar            # 2. dump 归档
java -XX:SharedArchiveFile=app.jsa -jar app.jar           # 3. 启动(快)
# JDK 24 一行式:
java -XX:AOTCache=app.aot -jar app.jar   # 训练运行生成
java -XX:AOTCache=app.aot -jar app.jar   # 启动提速 2~3x
  • AppCDS:类加载阶段省 20%~40%,微服务典型省 0.5~2 秒;
  • AOT Cache(JDK 24/25):整体启动时间约 1/2~1/3(JIT 预热也跳过),峰值性能不受影响(C2 运行时照常接管)。

适用场景(工程判断):Serverless 冷启动、CLI 工具(javac 自身就靠 CDS 提速)、频繁重启的 K8s 弹性场景、多进程共享(同镜像下的 sidecar)。注意:归档与 classpath/JVM 版本绑定(变更要重新 dump,CI 里做成构建步骤);Dockerfile 里把 dump 和运行分层,别每次启动现 dump。