本期检索说明
先读取 content/collections/deep-radar 截至 2026-09-22 的全部原文链接,并按 URL、标题、实现机制与补丁身份去重。最近 24 小时只有 1 项同时给出源码差异、公开实测和机制解释;回溯最近 7 天后补充到 2 项。二者都来自 HotSpot CDS/AOT cache 创建与启动链路,近期 Java 覆盖偏多,但 Kotlin、Rust、Zig、Linux 新候选要么缺少独立 benchmark,要么把目标改动与叠加改动混在同一组数字中,因此本期没有为领域均衡而降低证据标准。
两项结果都来自 Spring PetClinic,且没有公开运行次数、方差、硬件、JDK 参数或置信区间。第一项给了原始时间,却把 1.936 → 1.740 s 描述成 12%:按这两个数计算实际下降约 10.12%。第二项只给 2.5% 汇总值。它们足以证明路径值得调查,不足以外推成所有 CDS/AOT 工作负载的稳定收益。
| 主题 | 原始发布日期 | 一手来源与交叉验证 | 截稿状态 | 推荐强度 |
|---|---|---|---|---|
MetaspaceClosure::Ref 按需堆分配 |
2026-09-21 18:07(中原标准时间) | OpenJDK PR #32979 / JDK-8392765 / 3 commits / Spring PetClinic AOT cache create | 开放评审,tier1–tier2 运行中 | 推荐,重点看生命周期重写 |
| CDS 空 loader constraint 快路径 | 2026-09-22 18:49(中原标准时间) | OpenJDK PR #33005 / JDK-8392815 / JDK-8178349 / 1 行 patch / PetClinic time-to-first-request | 已有 2 名 reviewer,待集成 | 推荐,但数字证据较薄 |
01 · JVM:让 Ref 常态栈分配,只为递归溢出路径克隆
原文与日期: Johan Sjölén,2026-09-21 18:07(中原标准时间);OpenJDK PR #32979、JDK-8392765 与 完整源码 patch。
为什么值得读: 这是一个典型的“为了稀有逃逸路径,让所有对象都付出堆分配成本”案例。MetaspaceClosure 遍历类元数据时需要携带类型化的 Ref 包装;旧实现因为深度达到 5 后可能把 Ref 挂到 _pending_refs 链表,便把每个普通节点也先 new 到 C heap,再在同步递归完成后 delete。补丁重新划定所有权:常态对象放栈上,只有真的要跨越当前栈帧保存时才虚拟克隆到堆上。
核心技术结论: push_with_ref 与 push_c_array 从无条件 new 改为局部变量;push_impl 在 _nest_level < MAX_NEST_LEVEL 时直接同步消费栈对象,不再 delete。达到深度上限时才调用虚函数 clone(),复制具体 MSORef、GrowableArrayRef 或 CArrayRef,并把 clone 链入 _pending_refs。finish() 仍负责逐个 do_push 和 delete 这些真正逃逸的对象。
template <class REF_TYPE, typename T>
void push_with_ref(T** mpp, Writability w) {
REF_TYPE ref(mpp, w);
push_impl(&ref);
}
void MetaspaceClosure::push_impl(Ref* ref) {
if (_nest_level < MAX_NEST_LEVEL) {
do_push(ref); // 栈对象在调用期间始终有效
} else {
Ref* cloned_ref = ref->clone(); // 只有需要延迟处理才逃逸
cloned_ref->set_next(_pending_refs);
_pending_refs = cloned_ref;
}
}这里不能简单删除堆分配:MAX_NEST_LEVEL 固定为 5,超过后必须把工作推迟到 finish(),原栈帧届时已经消失。新增虚拟 clone() 正好把“会不会逃逸”的判定推到运行时分岔点,同时保留 Ref 的 NONCOPYABLE 约束,避免无意值拷贝。patch 还确保 enclosing_obj 标签在 clone 上恢复,否则 AOT archive 记录嵌入指针时会丢失所属对象。
最有价值的实验、源码与 benchmark 细节: Spring PetClinic 创建 AOT cache 的 wall clock 从 1.936 秒降到 1.740 秒,绝对减少 196 ms;按公开原始值计算为 10.12%,并非 PR 正文声称的 12%。作者还试过 Arena 批量分配,确认它也能减轻 malloc 成本,但收益更小且不能逐个释放 Ref,增加了内存占用;这组负向实验说明问题不只是 allocator 吞吐,还包括常态对象根本不应进入 heap。
数据仍只有“一次运行”的公开表述,没有方差、allocation count、malloc profile 或 RSS。工程复测应至少同时采集 perf record/JFR Native Memory、C heap allocation 次数、AOT cache 大小和 20 次以上 wall clock;还要构造深度超过 5 的 metadata graph,确认 clone 慢路径的比例和峰值内存没有恶化。
适合的工程师背景: 熟悉 CDS/AOT cache、HotSpot 元数据布局、C++ RAII 与逃逸生命周期,或正在把“偶发异步保存”从高频对象路径中剥离的运行时工程师。
预计阅读收益: 约 45–70 分钟;能掌握用“栈上默认 + 逃逸时虚拟克隆”替代全量堆分配的完整生命周期证明,并学会从作者百分比回到原始数值复算。
02 · JVM:空 loader constraint 不应触发 vtable/itable 重建
原文与日期: Johan Sjölén,2026-09-22 18:49(中原标准时间);OpenJDK PR #33005、JDK-8392815、1 行源码差异 与前序优化 JDK-8178349。
为什么值得读: patch 只把 return true 向外移动一层,却改变了 CDS 恢复类的昂贵控制流。它展示了性能工程中非常常见的语义漏洞:函数返回值表达的是“是否需要重建”,而旧代码却把“没有待验证约束”落进 false 分支,与“约束验证失败”混为一谈。
核心技术结论: SystemDictionaryShared::check_linking_constraints 的契约是:仅当需要重新初始化 klass 的 vtable/itable 来检查 class-loader constraints 时返回 false。boot loader 类直接为 true;platform/app loader 类如果记录了约束,就逐条调用 SystemDictionary::add_loader_constraint,任何冲突返回 false。旧代码只在 num_loader_constraints() > 0 分支末尾返回 true,于是数量为 0 时继续落到底部 false。补丁把 true 移到 platform/app loader 外层:零约束是 vacuous success,不应触发重建。
if (klass->defined_by_platform_loader() || klass->defined_by_app_loader()) {
RunTimeClassInfo* info = RunTimeClassInfo::get_for(klass);
if (info->num_loader_constraints() > 0) {
for (...) {
if (!SystemDictionary::add_loader_constraint(...)) return false;
}
}
return true; // 有约束且全部成功,或根本没有约束
}逻辑上,这是把 all([]) 从错误的 false 恢复为 true。工程上,它避免 archived class 在绝大多数没有 loader constraint 的情况下反复初始化 vtable/itable。JDK-8178349 已经消掉一批不必要重建;本补丁补上前序优化遗漏的空集合分支,因此适合和前一条 Ref 改动一起看:两者都在消除 AOT/CDS 链路上“为可能发生的事预付成本”的模式。
最有价值的实验、源码与 benchmark 细节: 作者报告 Spring PetClinic 的 time-to-serving HTTP requests 改善 2.5%,并完成 tier1、tier2 与 builds-tier5。源码证据很强:只有 1 行位置变化,失败路径仍由 add_loader_constraint 明确返回 false;boot、自定义 loader 和有约束的 platform/app loader 行为均可逐分支审计。
但 benchmark 只公开相对值,没有绝对毫秒数、运行次数、方差、archive 创建参数或请求探针定义,因此 2.5% 只能视为定向信号。可靠复测应分别统计零约束与有约束 archived class 数量、vtable/itable reinitialize 次数、启动 CPU profile,并验证自定义 class loader 与故意制造 constraint violation 时仍走慢路径。
适合的工程师背景: 熟悉 CDS、class loading/linking、vtable/itable 初始化,或正在排查 Java 服务 time-to-first-request 的 JVM 性能工程师。
预计阅读收益: 约 30–45 分钟;能把 1 行 diff 还原成空集合逻辑、类加载约束契约和启动重建成本,并获得一套针对控制流快路径的验证清单。
中国大陆 ToC 硬件价格观察
数据口径
窗口为 2026-08-25 至 2026-09-23,单位人民币,六类硬件固定同一 SKU。今天通过公开比价页实时复核到 CPU、GPU、主板、HDD、SSD 五类报价;DRAM 页面仍明确显示“暂无报价”,因此不新增点。重复价格作为真实采样保留,用来区分“已复核横盘”和“未取得数据”。
SSD 本期修正历史口径:页面顶部“¥819 起”会跨容量聚合,即使当前规格显示 2TB,也不能当作 2TB 报价;今天只采用 2TB 的“全网比价”栏 ¥1,799。此前记录的 ¥749 同样来自不明容量页面起价,现已从 2TB 序列删除,避免在图上制造虚假的 140% 单日上涨。
| 类别 | 9 月 23 日可复核价 | 30 日窗口内真实走势 | 建议 |
|---|---|---|---|
| CPU | Ryzen 7 9800X3D,京东 ¥2,579 | 9/3 ¥2,599 → 9/9 ¥2,449 → 9/14 ¥2,639 → 9/22 ¥2,619 → 9/23 ¥2,579 | 观望或小幅回落时入手;日降 ¥40,但仍比窗口低点高 5.31% |
| GPU | MSI RTX 5070 VENTUS 3X 12G,亚马逊中国 ¥4,464.34 | 8/29–9/23 九个真实点均为 ¥4,464.34 | 刚需可比价后入手;该渠道横盘,京东同页为 ¥8,199,售后口径不可等同 |
| 主板 | ASUS TUF B850M-PLUS WIFI7,天猫 ¥1,299 | 8/31 ¥1,449 → 9/2–9/23 ¥1,299 | 刚需可入;较窗口首点低 10.35%,连续复核仍横盘 |
| DRAM | 暂无报价;最后可复核 9/9 ¥3,900 | 9/2 ¥3,900 → 9/5 ¥3,860 → 9/6–9/9 ¥3,900 | 观望;固定 SKU 当前缺价,不能用其他容量、颗粒或时序替代 |
| HDD | IronWolf Pro 8TB ST8000NE001,i百联 ¥1,849 | 9/1–9/23 八个真实点均为 ¥1,849 | 容量刚需可买;先核对型号、五年保修与数据恢复服务 |
| SSD | ZHITAI Ti600 2TB,京东 ¥1,799 | 9/2 ¥1,919 → 9/23 ¥1,799;中间页面起价因容量不明已剔除 | 观望;较可比首点低 6.25%,但公开样本只有两点且近期同页爆料为 ¥1,889–1,919 |
价格来源: 9800X3D、MSI RTX 5070 VENTUS 3X、ASUS TUF B850M-PLUS WIFI7、Kingston FURY DDR5-6000 32GB、IronWolf Pro 8TB、ZHITAI Ti600 2TB。
判断依据
CPU 今天回落 ¥40,但距离 9 月 9 日低点仍有 ¥130,尚不足以确认连续下跌。GPU、主板与 HDD 再次确认横盘;其中 GPU 的渠道价差仍远大于正常日波动。DRAM 缺价,不用相似套条补点。SSD 清洗掉容量不明的起价后,可比的 2TB 序列仅从 ¥1,919 降到 ¥1,799;样本稀疏且同页近期好价仍在 ¥1,889–1,919,不能据此断言零售市场已经稳定下跌。
其它你可能关心的
- Rust:减少目标 CPU feature 检查的 LLVM FFI 次数——源码机制清晰,但官方 rustc-perf 无 instruction 改善,cycles 还有 2.8% primary 回退。
- Rust:BTreeMap drop 改为按节点释放——benchmark 数量很多,但表格把 clone 改动与 drop 改动叠在同一基线,无法把主要收益归因给本 PR。
- Shenandoah:统一 remembered-set scan 小任务粒度——5 次 Retain workload 中 remset scan 平均下降 52%,但原始发布已超过 7 天窗口。
本期结论
两项 HotSpot 改动共同指向一个可迁移原则:不要让高频路径为低概率状态预付成本。MetaspaceClosure 用栈上默认、逃逸时 clone 消除全量 malloc/free;CDS 链接约束用空集合即成功的语义,消除无意义 vtable/itable 重建。前者原始数字实算约 10.12% 而非 12%,后者只有 2.5% 汇总值,两者都需要更完整的多轮与 profile 复测。硬件五类取得当日真实点;CPU 回落,GPU/主板/HDD 横盘,DRAM 留白,SSD 则完成一次必要的跨容量口径清洗。