伙伴系统

Linux的伙伴算法把所有的空闲页面分为10个块组,每组中块的大小是2的幂次方个页面,例如,第0组中块的大小都为2(1个页面),第1组中块的大小为都为21(2个页面),第9组中块的大小都为29(512个页面)。也就是说,每一组中块的大小是相同的,且这同样大小的块形成一个链表。

我们通过一个简单的例子来说明该算法的工作原理。

假设要求分配的块其大小为128个页面(由多个页面组成的块我们就叫做页面块)。该算法先在块大小为128个页面的链表中查找,看是否有这样一个空闲块。如果有,就直接分配;如果没有,该算法会查找下一个更大的块,具体地说,就是在块大小为256个页面的链表中查找一个空闲块。如果存在这样的空闲块,内核就把这256个页面分为两等份,一份分配出去,另一份插入到块大小为128个页面的链表中。如果在块大小为256个页面的链表中也没有找到空闲页块,就继续找更大的块,即512个页面的块。如果存在这样的块,内核就从512个页面的块中分出128个页面满足请求,然后从384个页面中取出256个页面插入到块大小为256个页面的链表中。然后把剩余的128个页面插入到块大小为128个页面的链表中。如果512个页面的链表中还没有空闲块,该算法就放弃分配,并发出出错信号。

以上过程的逆过程就是块的释放过程,这也是该算法名字的来由。满足以下条件的两个块称为伙伴:

·      两个块的大小相同

·      两个块的物理地址连续

伙伴算法把满足以上条件的两个块合并为一个块,该算法是迭代算法,如果合并后的块还可以跟相邻的块进行合并,那么该算法就继续合并。

2.数据结构

在6.2.5节中所介绍的管理区数据结构struct zone_struct中,涉及到空闲区数据结构:

free_area_t free_area[MAX_ORDER];

我们再次对free_area_t给予较详细的描述。

#difine   MAX_ORDER  10

type struct free_area_struct {

struct list_head   free_list

unsigned  int    *map

} free_area_t







 
   

其中list_head域是一个通用的双向链表结构,链表中元素的类型将为mem_map_t(即struct
page结构)。Map域指向一个位图,其大小取决于现有的页面数。free_area第k项位图的每一位,描述的就是大小为2k个页面的两个伙伴块的状态。如果位图的某位为0,表示一对兄弟块中或者两个都空闲,或者两个都被分配,如果为1,肯定有一块已被分配。当兄弟块都空闲时,内核把它们当作一个大小为2k+1的单独快来处理。如图6.9给出该数据结构的示意图:

图6.9 伙伴系统使用的数据结构

图6.9中,free_aea数组的元素0包含了一个空闲页(页面编号为0);而元素2则包含了两个以4个页面为大小的空闲页面块,第一个页面块的起始编号为4,而第二个页面块的起始编号为56。

我们曾提到,当需要分配若干个内存页面时,用于DMA的内存页面必须是连续的。其实为了便于管理,从伙伴算法可以看出,只要请求分配的块大小不超过512个页面(2KB),内核就尽量分配连续的页面。

时间: 2024-10-13 00:16:50

伙伴系统的相关文章

堆管理算法中的Buddy System(伙伴系统)算法

在一个Buddy System算法中,堆管理者只分配特定大小的内存块,成为permitted size.针对每个permitted size,都有一个空闲链表来维护. 一般这些大小会选择2的幂次方,或者斐波那契数列.因为这样会方便地将除最小的那个数之外的其它数都分为两个permitted size之和. 当负责分配内存的堆管理者接受到请求s大小的内存请求时,会讲s对齐到一个permitted size.然后从那个permitted size的空闲链表中分配一块内存给他.如果没有在那个空闲链表中找

[linux内存]伙伴系统学习笔记(一)——概念

1,伙伴系统的作用: 伙伴系统主要是为了高效使用物理内存,尽量减少内存碎片的产生 2,伙伴系统的概念: 系统中的内存总是两两分组,每组中的两个内存块称为伙伴 3,伙伴系统的原理:  伙伴系统是相对于struct zone而言,将每个zone的空闲内存分为最多11个数组,比如第一个数组里管理着2^0页的内存,所有这些2^0的页以struct page的lru域的双向链表相连接,第二个数组管理着2^1页的内存,所有这些2^0的页以struct page的lru域的双向链表相连接,以此类推,.....

[Linux内存]linux内存学习(五)——伙伴系统

Linux伙伴系统(一)--伙伴系统的概述 Linux伙伴系统(二)--伙伴系统的初始化 Linux伙伴系统(三)--分配页 Linux伙伴系统(四)--释放页 Linux伙伴系统(五)--通过迁移类型分组来实现反碎片

伙伴系统之伙伴系统概述--Linux内存管理(十四)

日期 内核版本 架构 作者 GitHub CSDN 2016-09-02 Linux-4.7 X86 & arm gatieme LinuxDeviceDrivers Linux内存管理 1 前景回顾 1.1 Linux内存管理的层次结构 Linux把物理内存划分为三个层次来管理 层次 描述 存储节点(Node) CPU被划分为多个节点(node), 内存则被分簇, 每个CPU对应一个本地物理内存, 即一个CPU-node对应一个内存簇bank,即每个内存簇被认为是一个节点 管理区(Zone)

多核心Linux内核路径优化的不二法门之-slab与伙伴系统

作为这个系列的第一篇,我先来描述一下slab系统.因为近些天有和同事,朋友讨论过这个主题,而且觉得这个主题还算比较典型,所以就作为第一篇了.其实按照操作系统理论来讲,进程管理应该更加重要些,按照我自己的兴趣来讲,IO管理以及TCP/IP协议栈会更加有分量,关于这些内容,我会陆续给出. Linux内核的slab来自一种很简单的思想,即事先准备好一些会频繁分配,释放的数据结构.然而标准的slab实现太复杂且维护开销巨大,因此便分化出了更加小巧的slub,因此本文讨论的就是slub,后面所有提到sla

[linux内存]伙伴系统学习笔记(三)--分配器API

1,分配器API http://blog.csdn.net/kickxxx/article/details/9287003 伙伴系统只能分配2的整数幂个页.因此申请时,需要指定请求分配的阶. 2,分配页, 所有分配伙伴系统的函数分配页最终都会调用到alloc_pages_nodemask()函数 static inline struct page*alloc_pages_nodemask(int nid,gfp_t gfp_mask,unsigned int order)nid:指的是从哪一个节

[linux内存]伙伴系统学习笔记(二)--内存系统初始化

1,本文大部分来自:http://blog.csdn.net/vanbreaker/article/details/7611585 2,在start_kernel()-->paging_init()-->zone_sizes_init()-->free_area_init_nodes()-->free_area_init_node()-->free_area_init_core()-->init_currently_empty_zone()->zone_init_

linux伙伴系统接口alloc_page分析1

在内核中分配内存,最后要通过伙伴系统接口进行实际物理页面的分配,一个重要的接口便是alloc_page.本文介绍下alloc_page的主要流程,各个部分的执行.主要包含正常分配流程,当页面不足的时候的处理方式.先定位到核心调用 #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) order是分配页面的阶,即2的指数个页面 #define alloc_pages(gfp_mask, order) \ alloc_pages_node(num

看数据结构写代码(50)伙伴系统

伙伴系统 是一种 只 可以 分配 2的 幂次方 个 空间的 ,回收 内存 时 只 合并 "伙伴空间" 的一种 动态内存管理方式. 例如 一个 空间 大小 为 64 的 内存,伙伴 系统 为 这 64 的内存  建立 一组 双向循环 链表,分别 管理着  2的 0 次方,2的1 次方幂,2的 2 次方幂...2的6次方幂的 可用空间. 即使 我们 只想分配 一个 大小 为3的 空间,系统 却 只能 返回 一个 内存 大小 为 4(2的2次方)的 一个空间. 系统 在 初始化的 时候 ,并