linux内存管理---伙伴系统算法

来源:互联网 发布:网络监控软件破解版 编辑:程序博客网 时间:2024/05/29 04:37

伙伴系统算法:

该算法用于分配内存,一个合理的分配内存算法应当拥有这两部分:

  1. 分配内存
  2. 释放内存

符合以下三个要求的就算是伙伴:

  1. 两个块的大小相同
  2. 两个块的地址连续
  3. 两个块必须是从同一个大块分离出来的

原理:

linux把每个zone分成MAX_ORDER个free_area,每个free_are的大小是2的幂次方。MAX_ORDER的值为11,第0组大小为2^0个页,第1组大小为2^1个页,依次类推,最大的是2^10个页,即1024*4KB=4MB。同样大小的块形成一个链表。每个free_area都维护了一个位图,该位图表示所有的空闲块,有n个空闲块,则有n/2位,每位对应两个伙伴块,为0代表两块都空闲,为1表示其中一块忙。在每次分配或者释放时,都要进行异或运算,意思是,初始阶段两块都空闲,值为0;使用了其中一块之后,值异或为1;另外一块如果也使用了,值异或为0;其中一块释放两,值异或为1;两块都释放了,异或为0。

有关结构体:

struct free_area{    struct list_head free_list; //每个free_area链表的头结点    unsigned long    nr_free;   //空闲链表的数量};struct zone{    ....    struct free_area free_area[MAX_ORDER];    ....}

分配内存:

先找到等于或者最接近2的幂次方的链表,查看对应的free_area的nr_free是否还有剩余,如果有的话,则直接分配;如果没有的话,则从更大一级的free_area中寻找,如果有空的,就将该结点取出来,分成两半,称为伙伴,一半用于内存分配,另一半整合到小一级的free_area中;如果还是没有,则继续上面的过程。

释放内存:

释放内存其实是分配的逆过程,当释放一个块时,先查找对应的free_area中的链表中是否有伙伴存在,如果没有,则直接把释放的块插入free_area结构体成员free_list中;如果有的话,则将其伙伴从链表中取下,合并成一个大块,然后在这个大块对应的free_area中查找是否有伙伴,依次类推,直到不能合并为止。

优点:

  1. 减少了空闲分区,提高了空间利用率
  2. 可以分配连续的内存页面
  3. 适合大内存分配

缺点:

  1. 合并需要严格的条件,不是伙伴不能合并
  2. 如果两个大小相同的内存块之间有一个小的内存块,则这两个内存块不能合并
  3. 只能分配2的幂次方内存区,会造成浪费。比如需要17K时,就只能分配32K大小的内存空间,剩下的15K就被浪费了
  4. 由于是用链表和位图进行操作,算法开销比较大
0 0
原创粉丝点击