Linux 内核中常见内存分配函数
1.原理说明
Linux 内核中采 用了一种同时适用于 32 位和 64 位系统的内 存分页模型,对于 32 位
系统来说,两级页表足够用了,而在 x86_64 系 统中,用到了四级页表,如图 2-1 所示。四
级页表分别为:
* 页全局目录(Page Global Directory)
* 页上级目录(Page Upper Directory)
* 页中间目录(Page Middle Directory)
* 页表(Page Table)
页全局目录包含若干页上级目录的地址,页上级目录又依次包含若干页中间目录的地址,
而页中间目录又包含若干页表的地址,每一个页表项指 向一个页框。Linux 中采用 4KB 大
小的 页框作为标准的内存分配单元。
多级分页目录结构
1.1.伙伴系统算法
在实际应用中,经常需要分配一组连续的页框,而频繁地申请和释放不同大小的连续页
框,必然导致在已分配页框的内存块中分散了许多小块的 空闲页框。这样,即使这些页框
是空闲的,其他需要分配连续页框的应用也很难得到满足。
为了避免出现这种情况,Linux 内核中引入了伙伴系统算法(buddy system)。把所有的
空闲页框分组为 11 个 块链表,每个块链表分别包含大小为 1,2,4,8,16,32,64,128,
256,512 和 1024 个连续页框的页框块。最大可以申请 1024 个连 续页框,对应 4MB 大小的
连续内存。每个页框块的第一个页框的物理地址是该块大小的整数倍。
假设要申请一个 256 个页框的块,先从 256 个页框的链表中查找空闲块,如果没有,就
去 512 个 页框的链表中找,找到了则将页框块分为 2 个 256 个 页框的块,一个分配给应用,
另外一个移到 256 个页框的链表中。如果 512 个页框的链表中仍没有空闲块,继续向 1024
个页 框的链表查找,如果仍然没有,则返回错误。
页框块在释放时,会主动将两个连续的页框块合并为一个较大的页框块。
1.2.slab 分 配器
slab 分配器源于 Solaris 2.4 的 分配算法,工作于物理内存页框分配器之上,管理
特定大小对象的缓存,进行快速而高效的内存分配。