降低复制算法内存开销的关键在于削弱多核硬件连锁副作用,包括缓存行震荡、MESI广播风暴和频繁内存屏障;通过按核隔离分配与复制、控制复制粒度与屏障节奏、延迟复制与按需克隆、缓存行友好布局等策略实现优化。

降低复制算法中对象移动的内存开销,关键不是减少“复制动作”本身,而是削弱它在多核硬件上的连锁副作用——尤其是缓存行震荡、MESI广播风暴和频繁内存屏障。这些开销远超单纯搬运字节的成本。
按核隔离分配与复制
让每个核心只在自己亲和的内存区域里完成分配和回收,避免跨核写入触发一致性协议:
- 将堆划分为 Per-Core Region(如每个 CPU socket 对应一个 NUMA 节点内的连续页),From/To 空间均限定在本核 L3 缓存覆盖范围内
- 分配时绑定线程到固定核心,对象初始落在对应区域;GC 时仅扫描+复制本区域存活对象,不跨核迁移
- HotSpot 的 G1 收集器已部分采用类似思路:Region 按地址局部性分组,复制优先选择同 NUMA 节点内相邻 Region
控制复制粒度与屏障节奏
避免为每个对象插入屏障,改用批量同步降低总线嗅探频率:
- 对连续复制的一批对象(如一个缓存行内多个小对象),只在整块复制完成后插一次 DMB ISH,而非每个对象后都加 Store-Release
- 利用 ARMv8.3+ 的 LDAPR/STLUR 指令做弱序原子读写,配合编译器 barrier hint,减少重排导致的冗余同步
- 若复制目标区此前未被其他核访问过,可先用 DC CIVAC 清理目标缓存行,避免首次写入触发 Write Invalidate 广播
延迟复制与按需克隆
避开“一律立即复制”的惯性设计,在读多写少场景下把复制动作推迟到真正修改时:
- 写时复制(Copy-on-Write):共享数据结构(如元数据快照、只读配置对象)维持原始引用,仅当某核首次写入时才复制私有副本并加屏障
- 对象引用层级分离:对大对象(如数组、ByteBuffer),只复制头部引用结构,底层数据页通过 mmap MAP_PRIVATE 共享,写入时由 OS 触发页级 Copy-on-Write
- 新生代中短命对象占比常超 95%,可结合逸出分析跳过逃逸对象的复制,直接在 Eden 原地晋升或复用
缓存行友好布局与填充
防止伪共享污染扩散,压缩单次复制引发的缓存失效范围:
- To 空间分配时强制 cache-line 对齐,并在对象末尾 padding 至 64 字节边界,确保不同对象不共享缓存行
- 对 From 空间中待复制的对象,按地址顺序批量读取,提升预取效率;复制目标地址也尽量保持步长一致,利于硬件预取器识别模式
- 禁用 To 空间所在页的硬件预取(如 x86 的 PREFETCHW 或 ARM 的 PRFM PLDL1KEEP),避免提前加载未使用数据挤占带宽

















