当前位置:首页 > 文章列表 > 文章 > java教程 > JVM Class Data Sharing怎样生成类数据归档缩短启动时间怎样完成一个可复用的最小示例

JVM Class Data Sharing怎样生成类数据归档缩短启动时间怎样完成一个可复用的最小示例

来源:17golang原创 2026-11-10 04:48:08 0浏览 收藏

我第一次把 Java 服务的启动优化从“调 JVM 参数”转到 Class Data Sharing(CDS)时,最容易混淆的是:归档不是把整个应用打包成一个更快的 JAR,而是把启动阶段实际加载的类保存为 JVM 可以更快映射的共享数据。先说结论:稳定的 classpath 应用可以用一次试运行生成 classlist,再用 -Xshare:dump 写出 .jsa 归档,启动时通过 -XX:SharedArchiveFile 使用;生产环境优先保留 -Xshare:auto,让不兼容时自动回退。

官方文档:https://docs.oracle.com/en/java/javase/21/docs/specs/man/java.html

这篇只讨论 JDK 21 命令行下的 AppCDS 最小闭环:记录类、生成静态归档、指定归档启动,以及 JDK 或启动参数变化后的处理。它不把“启动更快”写成无条件承诺,实际收益仍要用自己的应用基线测量。

先看问题现场:默认 CDS 和应用归档不是一回事

JDK 通常已经带有默认 CDS 归档,-Xshare:auto 会在可用时使用它。这个默认归档主要覆盖 JDK 运行时类;AppCDS 则进一步记录应用实际用到的类。Oracle 文档还提醒,归档类会以优化后的格式存储,归档文件可能比对应 JAR 中的类数据更大,因此应围绕真实启动路径收集,而不是把所有依赖都想当然地塞进去。

我会先把边界固定为三个对象:应用 JAR 和依赖构成的 classpath、试运行输出的 classlist、最终由 JVM 读取的 app.jsa。它们之间的关系如下图所示。

JVM Class Data Sharing 中应用 classpath、classlist、Xshare dump、共享归档与启动 JVM 的静态关系说明图
图1:静态结构说明图,查看应用 classpath、类列表、归档生成器与启动 JVM 之间的关系;这不是运行截图或实测结果。

动手验证:先记录一次真正加载过的类

静态 AppCDS 的第一步是让应用在关闭前把加载过的类名写入列表。下面用占位的 app.jar 和主类 com.example.Main 表示命令形态;实际项目要把它们替换成自己的启动入口,并保持后续生成归档时的 classpath 一致。

# 试运行应用,记录启动阶段真正加载过的类
java -Xshare:off \
  -XX:DumpLoadedClassList=app.classlist \
  -cp "app.jar:lib/*" \
  com.example.Main

-Xshare:off 是为了让这次记录不依赖已有共享归档;DumpLoadedClassList 只负责产出类名列表。这个命令本身不是性能结论,也不应把一次试运行当成所有流量路径的完整覆盖。若某些类只在登录、定时任务或特定请求中加载,试运行场景应尽量覆盖这些启动期分支。

定位原因:用 classlist 生成可复用的 .jsa

有了列表后,使用同一套 classpath 调用 -Xshare:dump 生成静态归档。归档文件名可以按 JDK、平台和应用版本分开管理,避免发布时把不匹配的文件误当成通用缓存。

# 使用上一阶段的类列表生成应用级静态归档
java -Xshare:dump \
  -XX:SharedClassListFile=app.classlist \
  -XX:SharedArchiveFile=app.jsa \
  -cp "app.jar:lib/*"

这里最关键的不是参数数量,而是输入关系:app.classlist 描述类,-cp 决定类从哪里解析,app.jsa 是输出文件。把归档复制到另一台机器或换成另一个 JDK 后,不能假设仍然可用;归档要和运行时、类路径以及影响类布局的关键参数一起作为发布产物管理。

JVM Class Data Sharing 中 SharedArchiveFile、JDK 运行时、classpath、Xshare auto 与应用启动的静态边界关系图
图2:运行时边界说明图,展示 JVM 使用共享归档时需要同时匹配的 JDK、classpath 与启动参数;这不是运行截图或实测结果。

修复方案:启动时指定归档,并保留自动回退

归档生成后,应用启动命令增加 -XX:SharedArchiveFile=app.jsa。生产启动一般使用默认的 -Xshare:auto,这样归档因为环境差异不能使用时,JVM 仍可按普通路径启动。-Xshare:on 更适合测试归档是否真的被接受;Oracle 文档明确提示它不应作为生产环境的常规选项。

# 生产倾向:归档可用就使用,不可用时允许 JVM 回退
java -Xshare:auto \
  -XX:SharedArchiveFile=app.jsa \
  -cp "app.jar:lib/*" \
  com.example.Main

# 诊断倾向:要求必须使用共享类数据,不能用于生产兜底
java -Xshare:on \
  -XX:SharedArchiveFile=app.jsa \
  -cp "app.jar:lib/*" \
  com.example.Main

如果只是想减少维护一次静态 classlist,也可以了解 -XX:+AutoCreateSharedArchive 这类自动创建方式;但在发布流水线里,我更愿意先把归档输入、JDK 版本和 classpath 固定下来,再明确决定是否采用自动生成。这样排查启动差异时,能知道归档到底由哪些输入产生。

验证结果:把“归档不可用”当作发布边界处理

当归档没有生效时,优先按下面的顺序对照:第一,生成归档和启动应用是否使用同一 JDK;第二,app.jar:lib/* 是否发生增删或顺序变化;第三,是否修改了会影响 JVM 类布局或启动行为的参数;第四,是否误把 -Xshare:on 带进了生产。修复后重新生成归档,比强行复用旧的 .jsa 更可靠。

场景建议
本地确认归档能否被接受临时使用 -Xshare:on,失败就回到输入匹配问题
生产部署使用 -Xshare:auto,按版本和运行时保存归档
依赖或 JDK 发生变化重新试运行、生成 classlist 和 .jsa

常见问题

只生成 app.jsa,不改启动命令,会自动使用吗?

不会把自定义归档当成无条件自动发现。应在启动参数中通过 -XX:SharedArchiveFile 指定它,并让 -Xshare:auto 负责可用时启用。

AppCDS 能代替应用启动性能基线吗?

不能。它针对类加载和共享数据布局,启动时间还会受到磁盘、容器资源、网络连接和应用初始化逻辑影响。应在相同环境下比较启用前后的多次启动结果。

我对这套最小闭环的判断是:AppCDS 最适合作为“发布产物的一部分”来管理,而不是一条永远不变的 JVM 参数。只要把 JDK、classpath、类列表和归档文件绑定在同一个版本上下文里,遇到归档失效时就能重新生成,而不是盲目追问某个参数为什么突然不生效。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Java record 反射怎样读取 record 组件并保持字段顺序怎样在批处理代码中减少额外分配Java record 反射怎样读取 record 组件并保持字段顺序怎样在批处理代码中减少额外分配
上一篇
Java record 反射怎样读取 record 组件并保持字段顺序怎样在批处理代码中减少额外分配
sealed class 模式匹配怎样让 switch 在类型层次变化时及时报错怎样完成一个可复用的最小示例
下一篇
sealed class 模式匹配怎样让 switch 在类型层次变化时及时报错怎样完成一个可复用的最小示例
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    965次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    966次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1077次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1057次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    888次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码