buddy allocator 与伙伴系统分配
这页讲的是:内核不只是要分小对象,也必须能从更底层把物理页按块拿出来,供应页表、页缓存、DMA 缓冲和上层分配器继续使用。学这页的重点,是理解 buddy allocator 更像“按 2 的幂组织物理页块的底层仓库”,它解决的是页级供应与合并回收问题。
这块是什么
buddy allocator 与伙伴系统分配,讲的是 Linux 怎样把物理内存页按不同阶数组织成可拆分、可合并的页块池,让系统能比较高效地拿到 1 页、2 页、4 页乃至更大的连续物理页。它关注的是“底层物理页块怎么供应和回收”,而不是直接面向业务对象的高频小块分配。
可以把它理解成:仓库里不是只有散装零件,而是把箱子按 1 箱、2 箱、4 箱、8 箱这种规格分层摆放。谁来要几箱,就先找最接近的整箱,不够合适时再拆;归还时如果隔壁那箱也空了,就再合并回更大的箱。
它负责什么
供应页级内存块
- 给上层页分配需求提供基础页块
- 支持不同大小的连续物理页申请
- 让页缓存、页表和很多内核路径都有底层页来源
- 把物理页供应做成正式体系
在拆分与合并中控制碎片
- 大块不够合适时可以往下拆
- 空闲相邻页块可以往上合并
- 尽量维持未来还能拿到较大连续块的机会
- 让物理页管理不至于越来越零碎
为更上层分配器兜底
- slab/slub、页缓存和很多映射路径最终都要向它要页
- 它决定系统还能不能拿出合适页块继续运转
- 底层供给紧张会往上层一路传导
- 让“缺页块”成为系统级资源问题而不是局部小事
为什么它不是“把内存随便切一切”
| 如果想得太简单 | 会怎样 | 真正关键在哪 |
|---|
| 觉得页分配只是拿几页出来 | 会忽略连续物理页大小和碎片压力。 | 底层难点是既要能拿,又要尽量别把未来的大块机会切没。 |
| 把它和 slab/slub 当成同一层 | 会混淆页块供应和对象分配。 | 伙伴系统更底层,先解决页从哪里来。 |
| 只看申请成功一次 | 会漏掉长期运行后外部碎片越来越严重的问题。 | 它真正面对的是系统长期供应能力。 |
| 觉得释放就是原样放回 | 会低估合并策略对未来大块分配成功率的重要性。 | 回收阶段同样在决定内存版图会不会继续变坏。 |
关键概念
| 概念 | 现在怎么理解 |
|---|
| buddy allocator | 按 2 的幂阶数管理连续物理页块的底层分配体系。 |
| order | 页块大小层级;order 越高,代表连续页块越大。 |
| 拆分 | 大页块不必整块都给出去,可以往下拆成更小伙伴块使用。 |
| 合并 | 相邻且同阶的空闲伙伴块有机会重新拼成更大页块。 |
| 外部碎片 | 总空闲量也许还够,但足够大的连续页块已经很难凑出来。 |
为什么重要
- 它解释了为什么内核会一边关心总内存压力,一边又单独关心“大块连续页还能不能拿出来”。
- 很多高阶分配失败,并不代表内存总量彻底见底,而常常是碎片化让合适页块已经很难凑齐。
- 理解这层后,你会更容易把页级供应、slab/slub、DMA、CMA 和内存回收放到同一张图里。
- 它让你看到:底层页分配不是静态库存,而是在不断拆分、合并和被上层消耗的动态版图。
常见误解
- 误解一:伙伴系统就是一个性能实现细节。实际上它直接决定很多页级需求能否成立。
- 误解二:有空闲页就一定能满足连续页申请。实际上连续性常比总量更稀缺。
- 误解三:只有驱动才关心高阶页。实际上页表、缓存和很多内核路径都会受底层页块供给影响。
它不负责什么
- 它不直接管理小对象缓存;那更像 slab/slub 这样的上层对象分配问题。
- 它不定义虚拟地址该映到哪里;地址空间和页表映射是别的层次。
- 它不自动消灭所有碎片;长期运行下仍需要回收、迁移和更高层策略一起配合。
和其他模块的关系
| 相关模块 | 关系 |
|---|
| slab / slub | 很多对象分配最终要先从伙伴系统拿页,再在页内继续切对象槽位。 |
| 页缓存与回收 | 回收效果和页块能否重新整理出更大连续块,常会影响底层供应质量。 |
| DMA / CMA | 需要连续物理内存的路径会更直接感受到高阶页块和碎片压力。 |
| vmalloc | 当物理连续难拿时,vmalloc 则是在虚拟地址层绕开这件事的另一种思路。 |
读完这页后,你应该能回答
- 为什么伙伴系统真正管理的是“连续物理页块怎么供应和合并”,而不是普通对象分配?
- 为什么总空闲内存还不少时,高阶页申请仍然可能失败?
- 为什么 buddy allocator、slab/slub、vmalloc 和 CMA 常常需要放在一张图里一起看?
后面适合继续问:高阶页失败最容易和“内存不够”混在哪?外部碎片为什么会让很多问题看起来像随机失败?如果对象不需要物理连续,为什么还要费力拿高阶页?