Skip to content

算法Algorithm

伙伴页分配与连续块合并

Binary buddy allocation · Buddy system · 伙伴系统

用对齐的幂二块分裂与合并管理连续页框,复算异或伙伴、内部碎片,以及空闲总数足够却无法满足大块请求的边界。

有8个空闲页框,不代表能交出一个连续8页的区域。物理页框分配已经说明谁拥有一页、何时能重新使用它;本页再要求若干页连续,并研究怎样用简单的分裂与合并保留这种形状。

形式陈述 ​

块的大小和起点一起受约束 ​

教学池MEM-16有16个页框,相对编号为0到15。每页256字节;本页只用页数计量。整个池作为一个根块,所有块都在它的二叉分裂树中。一个 order k 块覆盖 2k 页,起点 b 必须是 2k 的倍数,区间写作 [b,b+2k)。例如order 2允许起点0、4、8、12,不允许起点2。

分配请求 r 页,其中 1≤r≤16,选择最小的 k 使 2k≥r。若该层没有空闲块,向上找一个更大空闲块,并不断对半分裂,直到得到order k。为让手算结果唯一,本页在最小可用层中取起点最小的块;分裂时继续取左半,右半留作空闲。

每层有一份空闲块集合 Fk。另记已分配块及它的order;释放必须使用真实分配起点与order。集合中的块彼此不重叠,已分配块也不重叠;两者共同覆盖整个池。只把“用户实际用的3页”写进所有权记录,而忘了它拿走的是4页块,会把第4页错误地再次分配出去。

直觉

为什么伙伴只差一个二进制位 ​

order k 块的伙伴,是与它从同一个order k+1 父块分出来的另一半。用相对页框编号计算,伙伴起点为

b′=bxor2k.

起点 b 的低 k 位全为0;再往上一位决定它在父块的左半还是右半。翻转这一位恰好切换左右,而保留更高位表示的共同父块。比如order 2的块8,二进制是1000,异或0100得到1100,即伙伴12。

释放块时先找这个特定伙伴。只有伙伴也完整地空闲在同一层,才能从 Fk 删除它,并把二者组成的父块拿到上一层继续检查。相邻的两个块不一定是伙伴:[4,8) 与 [8,12) 虽然紧挨着,却分别属于父块 [0,8) 与 [8,16),不能直接拼成一个本模型允许的order 3块。

这个限制使合并不必遍历所有相邻洞。起点、层数和空闲状态足以确定候选者;若空闲集合支持常数期望时间的查询与删除,最多经过 log2⁡16=4 层。这个层数界不包含锁竞争、元数据存取或迁移已用页的成本;伙伴合并本身不搬动已分配内容。

例子与边界

从一个16页块拿出3页 ​

初始只有 F4={0}。请求3页要order 2,分配步骤如下。

动作 继续处理的块 新留下的空闲块
16对半成8 [0,8) [8,16),order 3
8对半成4 [0,4) [4,8),order 2
交付4页 [0,4) 已分配 不再分裂

实际请求3页,实际占用4页,块内有1页暂未用于这次请求。它是内部碎片,不是可被另一个页框请求随意取走的空闲页。若只统计用户有效需求,利用率是 3/4;若统计分配器已交付页数,分子则是4。两种统计不能混用。

总空闲8页,8页请求仍失败 ​

现在重置实验:先把16页分成四个已经交付的4页块,起点依次0、4、8、12。释放起点0和8后,空闲集合为 F2={0,8},总空闲8页,却没有order 3或更大块。0的伙伴4仍在使用,8的伙伴12也仍在使用,不能合并。

空闲数量与可分配形状分开检查

随后释放起点4的块。它的伙伴 4xor4=0 正在 F2,二者合成 [0,8),插入 F3。此时可以交付8页;起点8的4页空闲块仍独立保留,因为12尚未释放。请复算每一步的总量:释放三块后空闲12,交付8后空闲4,仍在使用的总量12。

若最初改为释放4和8,虽然得到连续区间 [4,12),标准二进制伙伴分配器仍不能用一个order 3块交付它,因为起点4不满足8页对齐。需要“任意连续8页”而不要求这种对齐的分配接口,可以有不同的成功条件;不能把不同分配器的合同混在一起。

异或公式不能越过池的边界 ​

公式使用相对同一根块的编号。本例16页是一段对齐根块;现实内存可能有孔洞、不同节点或不同分区,不能看到绝对页号异或后的数字存在,就跨区域合并。必须先确认两块属于同一可合并池。池起点若不是相应幂二对齐,直接把绝对地址代入也需要重新证明。

重复释放、释放块中间地址、或用错误order释放,都会破坏覆盖不变量。多核情况下,检查伙伴和删除伙伴还需要作为一个同步操作,避免两个释放者同时把同一空闲块拿去合并。正确的数学伙伴关系不自动解决并发所有权。

推论与应用

两种碎片要分别修复 ​

取 k=⌈log2⁡r⌉ 时,r≤2k<2r 对非幂二正整数成立;所以一次向上取整占用小于请求的两倍。这是单块内部碎片的界,不是“只要还有一半内存就能分配”的全局保证。交错占用仍可把大块全部截断。

伙伴合并只能聚合已经空闲的正确兄弟。若想让分散自由页变成更大连续区域,可能需要迁移可移动的在用页,更新映射,再释放旧帧;不能移动的页又可能挡住整个过程。大页映射需要对齐连续物理区域时,就会遇到这项额外约束。

它与对象堆分配也分工不同:本页按整页幂二块交付,几十字节对象通常由上层分配器在已取得的页内组织。复算终点应同时交出空闲集合、每个已分配块的起点与order、以及总量守恒;只报一个“剩余8页”不足以说明下一项请求能否成功。

参考资料
关系图谱5 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系