标记-整理算法以运行时开销换取内存连续性,核心代价包括数据迁移、页迁移、引用更新、触发抖动及低收益场景下的无效开销。

标记-整理算法确实能实现紧凑的内存布局,但它不是免费的——它用运行时开销换来了空间连续性。核心代价在于数据迁移本身:必须遍历所有存活对象、计算新地址、逐字节拷贝内容,并同步更新所有指向这些对象的引用。这个过程无法并行化到极致,且会阻塞应用线程(尤其在STW阶段),对延迟敏感场景影响显著。
页迁移带来直接性能损耗
整理的本质是物理页迁移。内核需为每个待迁移页分配新页框,拷贝全部数据,再批量更新页表项与反向映射结构。一次迁移涉及多次缓存行填充、TLB刷新和潜在的跨NUMA节点访问。实测表明,在高内存压力下,单次规整操作可能消耗毫秒级CPU时间,期间相关内存分配请求会被挂起。
引用更新开销被严重低估
不只是移动数据,更要修复所有“指针”。对于堆上对象,JVM或运行时需扫描GC Roots,再递归修正所有引用字段;Linux内核则要遍历radix树、反向映射链表,甚至处理KSM(Kernel Samepage Merging)共享页。这部分工作量随活跃对象数量线性增长,且难以预测——小对象多时,引用数量可能远超数据量本身。
触发时机不可控,放大抖动风险
- 被动规整常在分配大页失败后才启动,此时系统已处于内存紧张状态,CPU和IO负载本就偏高
- 主动规整虽可调度,但若频率过高,会持续抢占CPU周期;过低则碎片累积,导致后续更剧烈的STW
- 某些场景(如实时音视频服务)要求微秒级响应,而一次规整可能引入数百微秒抖动,直接违反SLA
并非所有碎片都值得整理
外部碎片(物理页不连续)可通过规整缓解,但内部碎片(页内未用空间)完全无解。更关键的是:现代应用大量使用mmap分配大块内存、或依赖huge page规避页表开销,此时规整收益极低,却仍要承担全部开销。嵌入式系统中,若RAM仅几十MB,规整带来的延迟可能直接导致看门狗复位。










