Linux内核伙伴系统(Buddy System)物理内存分配深度工程实战
一、引言:为什么需要伙伴系统?
在 Linux 内核的物理内存管理体系中,伙伴系统(Buddy System)是整个内存分配的基石。它负责管理物理页框(Page Frame)的分配与回收,解决外部碎片问题,并为上层的 Slab/Slub 分配器提供物理内存支持。理解伙伴系统,是深入 Linux 内核内存管理绕不开的第一步。
本文将从伙伴系统的核心原理出发,深入剖析其数据结构、分配/回收算法、迁移类型优化,并结合实际工程案例和 proc 接口调优,带你全面掌握这一经典算法在内核中的工程实现。
二、核心原理
2.1 基本思想
伙伴系统的核心思想是:将物理内存按 2 的幂次(order)组织成不同大小的内存块,分配时向上取整,释放时与"伙伴"合并成更大的块。
具体来说,系统维护 order 0 到 order 10(共 11 个等级)的自由链表:
- order 0:4KB(1 个页面)
- order 1:8KB(2 个页面)
- order 2:16KB(4 个页面)
- order 3:32KB(8 个页面)
- ...
- order 10:4MB(1024 个页面)
2.2 什么是"伙伴"?
两个内存块互为"伙伴"(Buddy),当且仅当:
- 两者大小相同(同一 order)
- 两者物理地址连续
- 两者合并后刚好是上一个 order 大小的两倍
- 第一个块的起始地址必须对齐到该 order 对应大小的边界
用数学表达:对于 order n 的块 A,其伙伴 B 的地址要么在 A 的前面(A 是后半部分),要么在 A 的后面(A 是前半部分)。判断的关键是:块起始地址的 2^n 位是否为 0。
三、核心数据结构
2.3 zone 与 free_area
伙伴系统的顶级组织单位是 zone(内存区域),典型的 zone 包括:
- ZONE_DMA:0-16MB,用于 DMA 操作
- ZONE_DMA32:0-4GB,32 位 DMA
- ZONE_NORMAL:直接映射区
- ZONE_MOVABLE:可迁移区
每个 zone 内部包含一个 free_area 数组,管理不同 order 的空闲链表:
struct zone {
struct free_area free_area[MAX_ORDER];
// ...
};
struct free_area {
struct list_head free_list[MIGRATE_TYPES];
unsigned long nr_free;
};
需要注意,每个 order 的自由链表还进一步按 迁移类型(MIGRATE_TYPES) 分离,这是内核为缓解碎片引入的关键机制。
2.4 页面标志与 PG_buddy
伙伴系统通过 PG_buddy 标志位来标识一个页面是否空闲在伙伴系统中:页面被释放时设置该标志,清除伙伴标志的时机则是在分配时进行。zone-

发表评论 取消回复