AppCDS通过预生成共享归档app.jsa并内存映射,跳过类解析、验证与加载,显著降低冷启动耗时;需先用-DumpLoadedClassList导出实际类列表,再以-Xshare:dump生成归档,启动时必须同时指定-Xshare:on和-XX:SharedArchiveFile才生效。

OpenJDK 用 CDS(Class Data Sharing)改善重复启动速度,核心就一条:把类元数据提前固化成共享归档文件,后续启动直接内存映射,跳过解析、验证、加载三步。它不是万能加速器,但对微服务、CI/CD 中频繁启停的 Java 应用,实测能压掉 30%–50% 的冷启动耗时。
怎么生成 app.jsa 归档文件
AppCDS 要求先有类列表,再用该列表生成归档。不能跳过类列表直接 dump —— 否则归档里只有系统类,你的 MainClass 和 Spring Bean 都不会进去。
- 先运行一次应用,导出实际加载的类列表:
java -XX:DumpLoadedClassList=app.classes -cp myapp.jar MainClass - 确保这次运行完整走完(比如 Spring Boot 启动到 “Started XXX in X.XXX seconds”),否则列表不全
- 用该列表生成归档:
java -Xshare:dump -XX:SharedClassListFile=app.classes -XX:SharedArchiveFile=app.jsa -cp myapp.jar - 注意:JDK 版本必须 ≥ 10(AppCDS 支持应用类),且 OpenJDK 构建需启用
--with-cds(主流发行版如 Zulu、Temurin、Liberica 默认支持)
启动时如何正确启用共享归档
光有 app.jsa 不启用等于白做。关键参数是 -Xshare:on 和 -XX:SharedArchiveFile,缺一不可;漏掉前者,JVM 会静默忽略归档文件。
- 启动命令必须包含:
java -Xshare:on -XX:SharedArchiveFile=app.jsa -cp myapp.jar MainClass - 如果看到警告
Unable to use shared archive或shared archive is disabled,大概率是:
–app.jsa路径写错或文件权限不足
– JDK 版本不匹配(比如用 JDK 21 生成的归档,被 JDK 20 启动时拒绝加载)
– 类路径(-cp)和生成归档时的不一致(哪怕多一个空格、少一个 jar) - 验证是否生效:加
-XX:+PrintSharedArchiveAndExit可查看归档加载详情;或启动后看日志是否有Loaded shared classes from
哪些场景下 CDS 会失效或效果极差
CDS 不是“设了就快”,它对运行时行为非常敏感。以下情况会导致归档被跳过、部分失效,甚至拖慢启动:
- 用了
-XX:+UseG1GC等非默认 GC(早期 JDK 中 CDS 仅与 Serial GC 兼容;JDK 12+ 已支持 G1,但仍需确认发行版是否 patch 过) - 应用动态生成类(如 Lombok @Data、CGLIB 代理、某些 JSON 库的运行时字节码增强),这些类无法预归档,每次仍要加载
- 启动参数中存在影响类加载顺序的选项,例如
-Dsun.misc.URLClassPath.disableJarChecking=true或自定义ClassLoader - Spring Boot 2.7+ 开启了
spring.aot.enabled=true(AOT 编译会绕过传统类加载路径,CDS 失效)
真正起效的关键不在参数多寡,而在「生成归档的那次运行」和「日常启动」的环境一致性:JDK 小版本、类路径、启动主类、甚至 java.library.path 都得对得上。稍有偏差,JVM 就会弃用归档——它宁可慢一点,也不加载可能不安全的数据。


















