标记-清除算法只回收不可达对象并归还内存至空闲列表,不管理碎片;空闲列表因不合并导致大小不一、地址离散,加剧外部碎片;位图法提升空闲状态可控性但不消除碎片;多级链表按尺寸分类空闲块以优化分配;合并相邻空闲块是抑制碎片的必要动作。

标记-清除算法本身不管理空闲块,它只负责识别并回收不可达对象,把它们的内存空间归还给空闲列表——真正决定“怎么用好这些空闲块”的,是后续的空闲块管理策略。
空闲列表是碎片的放大器
清除阶段将未标记对象的内存块逐个插入单向链表(free_list),但不做任何合并或排序。结果就是:空闲块大小不一、地址离散、彼此不连续。当新对象申请内存时,分配器只能在线性遍历中找一块够用的——这直接导致:
- First-fit易找到大块前段的小空闲区,留下大量难以利用的“夹缝”
- Best-fit虽节省空间,但频繁切分后残留更多微小碎片
- 无论哪种策略,只要不主动合并相邻空闲块,碎片就会持续累积
位图法让空闲状态更可控
相比链表式空闲列表,位图(Bitmap)用固定开销记录全堆块状态:1 bit 对应 1 块,0 表示空闲。优势在于:
Delphi 内存管理方面的指导性内容,摘录做成了PDF格式的电子书,本书是从一本Delphi书籍中摘录的内存管理那一章内容,不牵扯其它方面的内容,相对具有针对性。内容涉及遍历内存块、共享内存管理器、第三方内存管理器、Delphi内存管理实现框架、用户调用例程的实现等内容。
- 查找连续空闲区域更快(支持位运算扫描如 find-first-zero)
- 天然支持批量操作,例如一次标记数百块为已分配
- 与现代GC配合紧密,如G1和ZGC用位图加速并发标记,为后续整理留出时间窗口
但它不解决碎片本质问题,只是让碎片“看得见、管得住”。
多级空闲链表缓解分配压力
把空闲块按大小分类,维护多个独立链表(如:16B/32B/64B/128B/≥256B),能显著提升分配效率:
- 小对象分配不再扫完整个 free_list,直奔对应尺寸链表
- 大块集中管理,减少因误切大块造成的小碎片污染
- 部分实现还会定期合并同链表中相邻空闲块,抑制局部碎片增长
合并不是可选项,而是必要动作
清除阶段若只做“插入”,不检查前后块是否也空闲,就等于主动制造外部碎片。实际工程中必须加入合并逻辑:
- 在插入新空闲块时,检查其前驱和后继是否也在 free_list 中;若是,合并为一块
- 使用双向链表比单向更利于前向查找,但需额外存储指针开销
- 也可采用延迟合并:先标记“可合并”,等系统空闲时统一整理










