Clove: Object-Level CXL Memory Management in Managed Runtimes
一种面向托管语言运行时(如JVM)的对象级CXL内存管理系统,通过profile-guided对象热度追踪与对象压缩技术解决页内热度倾斜问题
Clove: Object-Level CXL Memory Management in Managed Runtimes
一、论文概述
| 项目 | 内容 |
|---|---|
| 标题 | Clove: Object-Level CXL Memory Management in Managed Runtimes |
| 作者 | Sam Son, Zhihong Luo, Wen Zhang, Sylvia Ratnasamy, Scott Shenker |
| 机构 | UC Berkeley / ICSI, Berkeley, USA |
| 论文 | arXiv:2605.20370 |
| 代码 | 无公开仓库 |
| 发布 | 2026-05-19 |
| 许可 | CC BY 4.0 |
| 页数 | 12页(含参考文献15页),13个图表 |
| 领域 | Operating Systems (cs.OS); Programming Languages (cs.PL) |
二、核心思想
问题定义
CXL(Compute Express Link)内存 tiering 系统中,现有方案主要基于虚拟内存,使用页面(4KB 或 2MB)作为热度追踪和数据迁移的粒度。然而,由于现代架构的页面尺寸远大于大多数程序对象,单个页面内可能包含多个访问频率差异巨大的对象——这种现象被称为页内热度倾斜(Intrapage Hotness Skew)。
即使采用最优的页面放置策略,也无法达到最优的快 tier 命中率。这一问题在使用 huge pages(2MB)时尤为严重:每个 2MB 页面包含约 7000 个 key-value 对,使得大多数页面因聚合热度而变为”温热”状态,导致命中率显著降低。
论文通过 Oracle 策略评估表明,在 10% 和 20% 的 fast-tier 容量比下,对象级管理相比 4KB 页面分别能获得 19.6 和 15.4 个百分点更高的快 tier 命中率。
为什么选择托管运行时?
传统对象级管理主要针对 C/C++ 等未托管语言,需要开发者重写数据结构或使用特殊编译器注解。Clove 的核心观察是:现有托管运行时(如 JVM、.NET CLR)已经提供了与对象级 CXL 管理高度相关的优化机制:
- 对象重定位:现代垃圾回收器(如 ZGC)已提供高效的对象移动和堆压缩机制
- 动态代码生成:JIT 编译框架支持在运行时观察程序行为并进行选择性代码插桩
解决方案概述
Clove 通过最小化扩展现有托管运行时来实现透明的对象级 CXL 管理,其核心设计包括:
- Profile-guided 对象热度追踪:利用 PEBS 硬件采样识别导致 L3 缓存缺失的”脱轨指令”,仅对这些指令对应的对象插入热度计数器
- 混合重定位方法:运行时负责将热对象紧凑排列到连续虚拟页面中,底层页面级系统负责物理页面迁移
- 精心的热对象压缩策略:通过热度阈值和区域选择水位线来控制压缩开销
三、技术架构
整体框架

Clove 的工作流程分为四个逻辑步骤:
- 在线分析:Profiler 使用 PEBS 收集 L3 缓存缺失样本,识别脱轨指令
- JIT 插桩:JIT 编译器将热度追踪逻辑插入脱轨加载指令前,在对象头中维护热度计数器
O.hot++ - 热对象压缩:在 GC 扫描阶段读取热度计数器,确定热度阈值,将超过阈值的对象重定位到专用区域
- 页面迁移:底层页面级系统检测到目标区域的页面变热后,将其迁移到本地内存
核心公式与设计要点
对象热度计数器(利用 JVM 对象头未使用的 16 位):
inc_counter(Register scr, Address header_addr) {
movzwq %scratch, %ax // 读取对象头
cmp %ax, $0xFFFF // 检查是否达到上限
je equal // 若达到上限则跳过
inc %ax // 递增计数器
movw %ax, 0x6(obj) // 写回对象头
equal:
... // 脱轨加载指令
}
该逻辑仅需 5 行汇编代码,且分支方向仅在计数器精确达到上限时变化,完全由分支预测器处理。
热度阈值确定:
Clove 在 GC 对象图扫描期间计算热度直方图,使用指数桶(第 i 个桶包含计数器值在 [2^i, 2^(i+1)) 范围内的对象)。计算从热到冷的累积和,当累积和首次超过本地内存大小时,将该桶及以上的对象分类为热对象。
区域选择策略:
基于两个可配置的水位线(低水位 5%、高水位 50%):
- 热对象比例低于低水位的区域:不值得处理(固定开销无法摊薄)
- 热对象比例高于高水位的区域:不需要压缩(已足够热)
- 仅选择热对象比例在两个水位线之间的区域进行额外重定位
模型组件
| 组件 | 说明 | 关键参数 |
|---|---|---|
| 在线 Profiler | 使用 PEBS 收集 L3 缓存缺失样本 | 采样率 1/2000,衰减比 1/2,每 1M 样本更新 |
| 热度追踪插桩 | 在脱轨加载指令前插入计数器递增逻辑 | 利用对象头未使用的 16 位空间 |
| 周期激活 | 背景线程每 N ms 激活 1ms 的热度追踪 | N=8/16/32 时无明显开销 |
| 热度阈值决策 | 基于直方图和本地内存容量动态确定 | 指数桶 [2^i, 2^(i+1)) |
| 区域选择 | 基于热对象比例的 watermark 策略 | 低水位 5%,高水位 50% |
| 混合重定位 | 运行时压缩热对象 + 页面级迁移物理页 | ZGC 2MB 区域 |
训练/运行流程
Clove 的运行流程:
┌─────────────────────────────────────────────────────────────┐
│ 应用执行中 │
│ │
│ PEBS采样 → 识别脱轨指令 → JIT插桩 O.hot++ │
│ ↓ │
│ GC扫描 → 读取热度计数器 → 构建直方图 → 确定阈值 │
│ ↓ │
│ 区域选择 → 重定位热对象到专用区域 │
│ ↓ │
│ 页面级系统检测热页面 → 迁移到本地内存 │
└─────────────────────────────────────────────────────────────┘
四、核心创新
| 创新点 | 说明 | 理论/实验依据 |
|---|---|---|
| Profile-guided 对象热度追踪 | 不直接对对象采样,而是先识别导致 L3 缺失的少量指令,再仅追踪这些指令涉及的对象的访问 | PEBS 在 1/2000 采样率下即可接近 100% 的指令覆盖率,运行时开销 <1% |
| 利用对象头存储计数器 | 复用 JVM 对象头未使用的 16 位空间存储热度计数器,避免额外元数据存储 | 仅需 5 条汇编指令,对象头通常在 L1 缓存中 |
| 周期激活机制 | 用背景线程周期性更新激活标志替代每事件的条件检查,消除分支预测失败开销 | N=8/16/32 时几乎零开销,而均匀采样会导致不可预测的分支 |
| 混合重定位 | 运行时负责热对象紧凑排列,页面级系统负责物理页迁移,职责分离 | 无需运行时感知物理页位置,同时自然处理跨页大对象 |
| 双水位线区域选择 | 基于热对象比例选择需要额外压缩的区域,平衡命中率提升与重定位开销 | 低水位 5%、高水位 50% 在多种应用中均表现良好 |
| 对象头锁冲突优化 | 采用乐观重试策略处理热度计数器更新与 CAS 锁操作的冲突 | 经确认并发数据结构中无明显额外开销 |
五、代码实现分析
实现基础
Clove 基于 OpenJDK 21 原型实现,修改了三个核心组件:
-
在线 Profiler:作为 JVM 内的原生后台线程实现
- PEBS 采样率:1/2000
- 衰减比:1/2(每 1M L3 缺失样本)
- 脱轨指令阈值:1%
-
C2 JIT 编译器:修改了两个部分以插入插桩逻辑
- 复用 ScopeDesc 数据结构,将脱轨指令的 IP 映射回原始字节码
- 在字节码解析和代码生成阶段插入 Load IR 节点,在最终代码生成时注入热度追踪逻辑
- 不干扰现有 C2 编译器优化
-
ZGC(区域式无暂停垃圾回收器):扩展了三个阶段
- 对象图遍历:读取热度计数器并构建直方图
- 区域选择:基于热对象比例选择额外重定位区域
- 重定位:将热对象移动到专用区域
关键技术细节
字节码到指令的映射:
| 字节码 | 内存操作数格式 | 偏移量 |
|---|---|---|
| getfield | [REG + offset] | 取决于字段 |
| getstatic | [REG + offset] | 静态字段偏移 |
| getarraylength | [REG + offset] | 数组长度偏移 |
| aload_* | [REG + offset] | 数组元素偏移 |
锁冲突处理:
当 CAS 操作失败时,检查对象头的低 48 位在 CAS 前后是否保持不变。如果不变,则判定为假失败并重试。
六、实验结果
评估设置
- 测试平台:CloudLab c6420,双路 Intel Xeon Gold 6142,每路 192GB DDR4
- CXL 模拟:通过 local-memory ballooning 机制模拟,测试 10%、20%、50% 三种本地内存比例
- 基线系统:TPP(NUMA hint faults)、Memtis(PEBS + 动态大页拆分)、HybridTier(计数 Bloom 过滤器)
- 应用:Ehcache(键值缓存)、JGraphT/PageRank(图算法)、H2/TPC-C(关系数据库)
端到端性能

合成工作负载:
- HotWarm 分布(20% 键占 90% 访问):在 20% 本地内存比例下,Clove 相比基线延迟降低 29-59%
- Zipfian 分布(0.99):在 10% 和 20% 本地内存比例下仍有明显优势

真实工作负载:
- Ehcache + Twitter-Large(160GB):延迟降低 29-59%
- Ehcache + Twitter-Medium(120GB):延迟降低 43-63%
- JGraphT/PageRank(120GB):性能改进 47-84%
- H2/TPC-C(120GB):延迟降低 22-47%
快 Tier 命中率

Clove 实现的本地内存命中率比 Memtis 高出 11-45 个百分点,且仅比理想 Oracle 策略低 4-5 个百分点,证明其实现了近最优的命中率。
页内热度倾斜量化

Oracle 策略评估显示,对象级管理在 10% 和 20% 的 fast-tier 容量比下,相比 4KB 页面分别获得 19.6 和 15.4 个百分点的更高命中率。2MB huge pages 的表现最差,因为每个页面包含约 7000 个 key-value 对。
组件因子分析
在线 Profiler 开销:

- 在 1/2000 采样率下,指令覆盖率接近 100%
- 运行时开销始终低于 1%
热度追踪 - 周期激活效果:
即使不启用周期激活,开销也仅为 4-5.5%(因为追踪逻辑本身很轻量)。周期激活(N=8/16/32)几乎消除了这一开销,而准确率几乎没有损失。
GC 开销:

- 额外的对象图扫描约每 6 分钟发生一次,持续 20-26 秒
- 重定位阶段每两次扫描触发一次,持续 15-27 秒
- 在 ZGC 下与应用程序并发执行,成本体现为缓存/内存争用而非停顿时间
- 扫描期间归一化延迟短暂升至 1.2×,随后迅速恢复
动态适应性:

与仅执行一次压缩的变体相比,Clove 的定期压缩能够持续适应热度变化,在第二次压缩后性能明显优于一次性方案。
压缩策略有效性:

- 无阈值策略(No Cutoff)会将温对象与热对象一起压缩,降低低本地内存比例下的性能
- 双水位线策略(5%/50%)在命中率和重定位时间之间取得了良好平衡
七、相关工作
| 类别 | 代表工作 | 与 Clove 的区别 |
|---|---|---|
| 页面级 CXL 管理 | TPP, Memtis, HybridTier, Nomad, FlexMem | 受限于页内热度倾斜,无法实现对象级精度 |
| 未托管语言对象级管理 | AIFM, MemLiner, OBASE | 需要开发者重写数据结构或使用编译器注解,不透明 |
| 硬件辅助子页管理 | PageSeer, Chameleon, MEMPod | 需要大量 SRAM 元数据,缺乏软件方案的灵活性 |
| JVM 内细粒度内存管理 | Panthera, Semeru, Polar | 针对特定问题(NVM 写入寿命、Spark 放置等),非通用 |
| 本地内存作为 L4 缓存 | Johnny Cache | 需要硬件支持,缺乏灵活性 |
Clove 是唯一专注于托管语言运行时扩展以实现透明对象级 CXL 管理的系统。
八、总结
核心贡献
- 新设计方向:提出将现有托管语言运行时扩展为对象级 CXL 内存管理的新设计方向
- 挑战识别与解决:识别了托管运行时扩展到 CXL 管理的三大挑战(透明度、物理页可见性、对象重定位策略),并通过新颖的热度追踪、混合重定位和系统化热对象压缩来解决
- 原型验证:在 OpenJDK 21 上实现了 Clove 原型,在有偏斜访问模式的真实工作负载下,相比最先进的页面级系统减少应用延迟 22-84%,且无需源代码修改
技术影响
- 证明了托管运行时中的 GC 重定位和 JIT 编译能力可以自然地复用于 CXL 内存管理
- 为其他托管运行时(.NET CLR、PyPy、V8/SpiderMonkey)提供了可扩展的设计范式
局限性
- 适用场景:针对热度在分钟到小时级别演变的内存密集型应用;每秒变化数百万/数十亿对象极端热度变化的工作负载不在范围内
- 堆外内存:原生分配和 I/O 缓冲区不参与 GC 重定位,只能由底层页面级系统管理
- 固定参数:当前使用固定的 PEBS 采样率、衰减比和水位线,自适应策略留作未来工作
九、参考资源
- 论文:https://arxiv.org/abs/2605.20370
- DOI:https://doi.org/10.48550/arXiv.2605.20370
- 许可证:CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
- 测试平台:CloudLab (https://www.cloudlab.us/)
- OpenJDK 21:https://openjdk.org/projects/jdk/21/
- ZGC:https://openjdk.org/jeps/439
- PEBS:Intel Timed Process Event-Based Sampling