JVM Class Data Sharing怎样生成类数据归档缩短启动时间为什么结果为空或不符合预期
JVM Class Data Sharing(CDS)归档不是把整个应用打包成一个更快的 JAR,而是把一次试运行中真正加载的类整理成 JVM 可直接映射的共享数据。要生成能命中的归档,关键是“试运行生成类表、用相同类路径 dump、启动时显式加载、再看 class load 日志”这四步。类表为空通常说明试运行没有成功走到应用入口;归档不生效则优先检查 JAR 是否被替换、类路径是否改变,以及是否带了会禁用 CDS 的模块参数。
官方文档:https://docs.oracle.com/en/java/javase/21/docs/specs/man/java.html
- 试运行必须使用
-Xshare:off -XX:DumpLoadedClassList,先得到真实类表。 -Xshare:dump时的类路径应与运行时相同或是运行时类路径的前缀,类路径中的 JAR 不能在 dump 后被修改。- 用
-Xlog:class+load看见source: shared objects file,才说明目标类命中了归档。
先用一次试运行生成 classlist
下面的示例假定应用入口是 com.example.Main,依赖都放在 lib/ 目录。类路径只写 JAR,不要直接放非空目录;这样得到的类表更接近后续可复用的归档边界。
# 关闭默认 CDS,避免试运行结果混入已有共享归档 java -Xshare:off \ -XX:DumpLoadedClassList=app.classlist \ -cp "app.jar:lib/*" \ com.example.Main # 先确认类表确实生成,并且包含应用自己的类名 wc -l app.classlist grep 'com/example/Main' app.classlist
如果 app.classlist 为零字节,先处理应用启动失败、入口类拼写、依赖缺失或进程提前退出。不要直接进入 dump 阶段,因为空类表只能得到没有应用类的归档。

用同一类路径生成并加载 JSA
有了类表后,用 -Xshare:dump 创建归档。dump 时的类路径必须覆盖类表中类的来源;运行时类路径可以是它的相同路径或前缀,但不要为了“精简”随意换 JAR 顺序。
# 使用与试运行一致的JAR类路径生成静态CDS归档 java -Xshare:dump \ -XX:SharedArchiveFile=app.jsa \ -XX:SharedClassListFile=app.classlist \ -cp "app.jar:lib/*" # 启动时加载自定义归档,并输出类加载来源 java -XX:SharedArchiveFile=app.jsa \ -Xlog:class+load \ -cp "app.jar:lib/*" \ com.example.Main
日志中若出现 com.example.Main source: shared objects file,说明这个类从归档读取。若显示为 JAR 路径,只能说明该类没有命中;不必把整次启动误判为 CDS 完全失效。
| 现象 | 优先检查 | 处理方向 |
|---|---|---|
| classlist 为空 | 入口、依赖、启动退出码 | 先让试运行完整走到业务入口 |
| JSA 生成但类仍来自 JAR | 类路径顺序、JAR 是否变化 | 恢复 dump 与运行时的一致路径 |
| 启动直接报 CDS 不可用 | JDK 构建、特殊 VM 参数 | 先用默认配置复现,再逐项加入参数 |
结果为空或归档被忽略时的边界排查
CDS 归档绑定的不只是类名,还绑定类的来源和 JVM 构建环境。dump 后替换 app.jar、改变依赖版本、调整类路径,都会让相应类退回动态加载。--patch-module、--limit-modules 和 --upgrade-module-path 等参数也可能禁用 CDS;排查时先去掉它们,再用最小命令确认归档命中。
如果目标是减少多进程的常驻内存,可以继续使用同一归档;如果只是想省去手工试运行,JDK 21 也支持 -XX:+AutoCreateSharedArchive。但自动归档同样要求后续启动使用同一 JDK 构建和相同命令行,不能把它当成任意环境通用的缓存文件。

常见问题
为什么生成了 app.jsa,启动却没有明显变快?
CDS 主要减少类元数据准备和部分启动工作,收益会受应用规模、磁盘和启动阶段占比影响。先用日志确认命中,再用多次冷启动对比,别只看一次耗时。
classlist 里没有业务类怎么办?
通常是入口没有真正执行到业务代码,或试运行使用了错误的类路径。先检查退出码和应用日志,再重新生成类表。
能把 JSA 文件复制到另一台机器吗?
不应把它当作跨 JDK、跨构建、跨应用版本的通用缓存。至少保持 JDK 构建、类路径和相关 JAR 内容一致,并重新用类加载日志确认。
实际落地时,先把“类表是否有内容”和“目标类是否来自 shared objects file”作为两个独立检查点。前者验证采集成功,后者验证归档真正参与启动,定位会比只看 JSA 文件是否存在更快。
MySQL 分区表怎样确认查询是否命中了分区裁剪怎样在批处理代码中减少额外分配
- 上一篇
- MySQL 分区表怎样确认查询是否命中了分区裁剪怎样在批处理代码中减少额外分配
- 下一篇
- 暂无
-
- 文章 · java教程 | 1天前 | 字符串处理 · java 分隔符 token 字符串解析 StringTokenizer returnDelims
- Java StringTokenizer 怎样把分隔符也作为 token 返回
- 318浏览 收藏
-
- 文章 · java教程 | 1天前 |
- Java 26 API 文档怎样按模块查找类
- 427浏览 收藏
-
- 文章 · java教程 | 1天前 |
- Java StringJoiner merge 为什么不保留对方前后缀
- 391浏览 收藏
-
- 文章 · java教程 | 1天前 |
- Java NIO FileChannel 怎样安全写入固定偏移
- 346浏览 收藏
-
- 文章 · java教程 | 1天前 | Java · 并发编程 · CompletableFuture · java completablefuture obtrudeException 异步异常恢复
- Java CompletableFuture obtrudeException 强制改写结果的处理边界
- 161浏览 收藏
-
- 文章 · java教程 | 1天前 | 依赖注入 · 单元测试 · java clock java.time 时间测试 InstantSource
- Java InstantSource 怎样为测试提供可替换的当前时间
- 258浏览 收藏
-
- 文章 · java教程 | 1天前 | nio · Java教程 · 文件系统 · java 文件属性 nio Files.readAttributes BasicFileAttributes NOFOLLOW_LINKS
- Java Files.readAttributes 怎样一次读取文件的基本属性
- 243浏览 收藏
-
- 文章 · java教程 | 1天前 |
- Java Stream 怎样避免并行流共享可变状态
- 268浏览 收藏
-
- 文章 · java教程 | 1天前 | java 线程中断 结构化并发 close StructuredTaskScope
- Java StructuredTaskScope close 的线程归属与资源回收边界
- 220浏览 收藏
-
- 文章 · java教程 | 1天前 |
- Java Map.copyOf 为什么不接受 null 键和值
- 104浏览 收藏
-
- 文章 · java教程 | 2天前 |
- Maven toolchains 怎样固定构建 JDK
- 458浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 952次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 959次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1071次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1043次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 877次使用
-
- Go Java 算法之字符串解码示例详解
- 2023-01-07 479浏览
-
- Go Java算法之单词搜索示例详解
- 2022-12-30 337浏览
-
- Gojava算法之括号生成示例详解
- 2023-02-22 128浏览
-
- GoJava算法之累加数示例详解
- 2023-01-07 149浏览
-
- GoJava算法最大单词长度乘积示例详解
- 2023-01-12 202浏览

