Linux内核:内存管理——伙伴系统

内存管理的伙伴系统

伙伴系统是linux内核中内存管理系统的基础。它负责以页为单位管理系统中的内存,申请分配、释放回收、避免内存碎片、虚拟内存中的页换出换入等活动。实际上来分析这个系统有点学术,但是对于修炼“内功”大有裨益,说不定什么时候就派上了大用场。下面会比较详细的分析内存伙伴系统。

还是和之前分析过程一样,我们首先概述一下这个系统中涉及到的主要数据结构,如下图所示,(1)在没有内存域中(ZONE),有一个per CPU变量pageset,这个结构管理这个域的单页分配工作,内核中分配单个页可能是最频繁的一项操作,如此频繁的操作如果直接从伙伴系统中分配单个页面,可能会引起伙伴系统频繁的拆分和合并大页,对系统性能造成比较大的冲击。所以用pageset这种机制做了个缓冲。(2)接下来就是fera_area,也就是伙伴系统,这里将page按不同阶链接在一起,一般MAX_ORDER等于11,也就是最大能分配2^11=2048个页面。(3)还需要说明一下的是每个阶不止一个page列表,为了避免内存碎片,内核引入了一个迁移列表的机制,就是将同一个类型的内存放在一个链表上,避免不可移动的页面被到处地方分配,引起内存碎片。

关于迁移列表机制的可以避免内存碎片的原理可以根据下面的例子来理解。比如下图中,每一个格子代表一个page,蓝色表示被分配了,很明显,系统只分配了很小的一部分内存,但是如果我想再分配连续的8个页面已经不可能了。

但是如果我们把内存区域按内存的用途分为不同的区域,比如将系统中不能搬移的页面限制到只能在上半部分分配,如下图所示。这样下班部分给可移动的页面使用,这样就避免了不可移动页面被分配到这个的内存空间中造成内存碎片。如下图所示,同样的内存使用情况,下图可以分配出来连续8页面的空间。

伙伴系统初始化

伙伴系统初始化除了给内存节点和内存域中相应的字段进行初始化工作外,最关键的工作就是分配得到一个page结构数组,因为在伙伴系统需要用page结构来表示每一个内存页。这个工作在自举内存分配器完成初始化之后就立即完成了。

最后内存节点中node_mem_map指向了该内存节点page数组的起始地址

free_area_init_node函数将内存节点各个域做相应的初始化,并初始化page数据结构。

在mem_init函数中,bootmem系统将逐一检查bitmap上空闲页面的位置,并将这些空闲的页面归还到伙伴系统中,同时将bootmem系统的bitmap也释放掉。

/*
* mem_init() marks the free areas in the mem_map and tells us how much
* memory is free.  This is done after various parts of the system have
* claimed their memory after the kernel image.
*/ 
void __init mem_init(void)
{
    unsigned int codesize, datasize, initsize;
    int i, node;
 
#ifndef CONFIG_DISCONTIGMEM
    max_mapnr   = virt_to_page(high_memory) - mem_map;
#endif 
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值