在系统初始化进行到伙伴系统分配器可以承担内存管理的责任后,必须停用bootmem分配器,毕竟不能同时用两个分配器管理内存。在UMA和 NUMA系统上,停用分别由free_all_bootmem和free_all_bootmem_node完成(前面的博客已经详细讨论过)。伙伴系统 基于一种相对简单而使人吃惊的强大算法,它结合了优秀内存分配器的两个关键特性:速度和效率。Linux内核中采用了一种同时适用于32位和64位系统的 内存分页模型,对于32位系统来讲,两级页表足够用了,而在x86_64系统中,用到了四级页表,四级页表分别为:node
页全局目录(Page Global Directory)算法
页上级目录(Page Upper Directory)跨域
页中间目录(Page Middle Directory)spa
页表(Page Table).net
页全局目录包含若干页上级目录的地址,页上级目录又依次包含若干页中间目录的地址,而页中间目录又包含若干页表的地址,每个页表项指向一个页框。Linux中采用4KBcode
大小的页框做为标准的内存分配单元。
在实际应用中,常常须要分配一组连续的页框,而频繁地申请和释放不一样大小的连续页框,必然致使在已分配页框的内存块中分散了许多小块的空闲页框。这样,即便这些页框 是空闲的,其余须要分配连续页框的应用也很可贵到知足。为了不出现这种状况,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个页框的链表查找,若是仍然没有,则返回错误。 页框块在释放时,会主动将两个连续的页框块合并为一个较大的页框块。
为清楚了解其分配制度,先给个伙伴系统数据的存储框图以下:
也就是每一个order对应一个free_area结构,free_area以不一样的类型以链表的方式存储这些内存块。blog
主要的数据域结构分析:内存