Java CDS 怎样缩短应用启动时间
来源:17golang原创
时间:2026-11-02 11:14:42 112浏览 收藏
Java CDS(Class Data Sharing)缩短启动时间的关键,不是把 Java 程序提前编译成另一种语言,而是让多个 JVM 复用已经整理好的类元数据。Oracle JDK 默认会尝试使用 CDS 归档;如果应用启动还要加载大量固定的业务类,可以再制作 AppCDS 动态归档,把应用类也纳入复用范围。
官方地址:https://docs.oracle.com/en/java/javase/24/vm/class-data-sharing.html
最小落地路径是:先保持生产启动命令不变运行一次,用-XX:ArchiveClassesAtExit生成动态归档;再用同一套 JDK、类路径和启动参数,通过-XX:SharedArchiveFile加载它。归档是启动优化的补充,不能替代应用本身的初始化治理。
先分清默认 CDS 和 AppCDS
默认 CDS 主要覆盖 JDK 核心类。JVM 启动时可以把归档中的只读元数据映射进进程,让多个 JVM 共享这部分内容;从 JDK 12 起,Oracle JDK 二进制通常会预置默认 CDS 归档。默认功能已经启用时,不需要先写一套复杂脚本。
当应用相对较小、但每次启动都要重复加载相同的业务类时,AppCDS 才更值得考虑。它把应用类路径中的选定类纳入归档,适合启动命令、依赖版本和运行方式都比较稳定的服务。

用一次试运行生成动态归档
动态归档的优点是步骤更少,通常也不必重复保存默认归档已经覆盖的类。下面假设应用由固定的 app.jar 启动,先用与生产一致的命令跑一遍,让 JVM 记录这次实际加载到的类:
# 用与生产一致的类路径运行一次,并在退出时写出动态 CDS 归档
java -XX:ArchiveClassesAtExit=app.jsa -jar app.jar
这里的 app.jsa 是归档文件名,实际部署时应放到稳定的发布目录。试运行覆盖到的代码路径越接近真实启动路径,归档越有机会覆盖稳定的启动类;但它不是把所有未来可能加载的类都预先收集进去。
如果应用的启动器很复杂,也可以让正在运行的 JVM 先以 -XX:+RecordDynamicDumpInfo 启动,再通过 jcmd 连接进程创建动态归档:
# 让 JVM 记录动态归档所需的信息;pid 替换为目标 Java 进程号
java -XX:+RecordDynamicDumpInfo -jar app.jar
# 从运行中的 JVM 导出动态归档,不改写应用自身的启动参数
jcmd VM.cds dynamic_dump app.jsa
两种方式都依赖真实的应用启动路径。不要为了“让归档更大”而随意扩大类路径,归档内容应服务于稳定的启动场景。
让后续 JVM 加载应用归档
生成归档后,后续启动命令增加 -XX:SharedArchiveFile:
# 使用动态归档启动同一个应用;类路径和 JDK 要与创建归档时保持一致
java -XX:SharedArchiveFile=app.jsa -jar app.jar
如果同时维护静态归档与动态归档,可以用平台对应的路径分隔符组合它们。Oracle 文档说明,静态归档先加载,动态归档再叠加;在 Windows 上,示例中的冒号需要换成分号:
# Linux/macOS 示例:先加载基础归档,再加载应用动态归档
java -XX:SharedArchiveFile=base.jsa:app.jsa -jar app.jar
生产上最重要的变化不是多加一个 JVM 参数,而是把归档文件和启动命令绑定到同一次发布。应用 JAR、依赖目录或启动参数变化后,应重新生成归档,而不是继续沿用旧文件。
归档为什么会失效
CDS 归档不是跨环境通用缓存。归档内容与创建它的 JDK 构建相关;类路径中的 JAR 被修改、运行时类路径与创建时不一致,或者模块相关参数变化,都可能让归档无法加载、只部分生效,甚至被禁用。
还要注意三个常见边界:带非空目录的类路径或模块路径不符合 CDS 的限制;--upgrade-module-path、--patch-module 和 --limit-modules 会禁用 CDS;-Xshare:on 适合测试归档是否能用,但官方不建议把它作为生产参数,因为归档不可用时 JVM 可能直接退出。

根据发布方式选择归档方案
| 场景 | 优先方案 | 原因 |
|---|---|---|
| 只想获得基础收益 | 保留默认 CDS | JVM 默认尝试加载核心类归档,改动最小 |
| 启动命令和依赖稳定 | ArchiveClassesAtExit + SharedArchiveFile | 能把应用启动类纳入动态归档,步骤清晰 |
| 启动脚本复杂但 JVM 可持续运行 | jcmd VM.cds dynamic_dump | 减少对启动脚本的侵入 |
| 希望按相同命令自动维护 | -XX:+AutoCreateSharedArchive | JDK 19 及之后可按归档文件和 JDK 版本自动创建或重建 |
最后不要只看单次启动耗时就宣布优化完成。至少要把归档文件作为构建产物管理,并在 JDK、依赖、类路径或模块参数变更时重新生成;如果归档被忽略,先检查启动条件是否一致,再决定是否继续保留这个参数。
相关问题
- Java CDS 默认需要手动打开吗?通常不需要,默认模式会在可用时尝试使用 CDS;可用
-Xshare:off关闭。 - AppCDS 能不能替代 JIT 优化?不能。CDS 主要减少类加载和元数据准备成本,不等于提前完成运行期 JIT 编译。
- 换了 JDK 还能继续用旧的 jsa 吗?不要直接假设可以。归档与 JDK 构建绑定,换 JDK 或关键启动条件后应重新生成并重新评估。
-
479 收藏
-
337 收藏
-
128 收藏
-
149 收藏
-
202 收藏
-
468 收藏
-
452 收藏
-
187 收藏
-
389 收藏
-
118 收藏
-
454 收藏
-
276 收藏
-
151 收藏
-
193 收藏
-
175 收藏
-
298 收藏
-
318 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习