Linux伙伴系统

伙伴系统的概述

Linux内核内存管理的一项重要工作就是如何在频繁申请释放内存的情况下,避免碎片的产生。Linux采用伙伴系统解决外部碎片的问题,采用slab解决内部碎片的问题,在这里我们先讨论外部碎片问题。避免外部碎片的方法有两种:一种是之前介绍过的利用非连续内存的分配;另外一种则是用一种有效的方法来监视内存,保证在内核只要申请一小块内存的情况下,不会从大块的连续空闲内存中截取一段过来,从而保证了大块内存的连续性和完整性。显然,前者不能成为解决问题的普遍方法,一来用来映射非连续内存线性地址空间有限,二来每次映射都要改写内核的页表,进而就要刷新TLB,这使得分配的速度大打折扣,这对于要频繁申请内存的内核显然是无法忍受的。因此Linux采用后者来解决外部碎片的问题,也就是著名的伙伴系统。

什么是伙伴系统?

伙伴系统的宗旨就是用最小的内存块来满足内核的对于内存的请求。在最初,只有一个块,也就是整个内存,假如为1M大小,而允许的最小块为64K,那么当我们申请一块200K大小的内存时,就要先将1M的块分裂成两等分,各为512K,这两分之间的关系就称为伙伴,然后再将第一个512K的内存块分裂成两等分,各位256K,将第一个256K的内存块分配给内存,这样就是一个分配的过程。下面我们结合示意图来了解伙伴系统分配和回收内存块的过程。

1 初始化时,系统拥有1M的连续内存,,允许的最小的内存块为64K,图中白色的部分为空闲的内存块,着色的代表分配出去了得内存块。

2 程序A申请一块大小为34K的内存,对应的order为0,即2^0=1个最小内存块

2.1 系统中不存在order 0(64K)的内存块,因此order 4(1M)的内存块分裂成两个order 3的内存块(512K)

2.2 仍然没有order 0的内存块,因此order 3的内存块分裂成两个order 2的内存块(256K)

2.3 仍然没有order 0的内存块,因此order 2的内存块分裂成两个order 1的内存块(128K)

2.4 仍然没有order 0的内存块,因此order 1的内存块分裂成两个order 0的内存块(64K)

2.5找到了order 0的内存块,将其中的一个分配给程序A,现在伙伴系统的内存为一个order 0的内存块,一个order

1的内存块,一个order 2的内存块以及一个order 3的内存块

3 程序B申请一块大小为66K的内存,对应的order为1,即2^1=2个最小内存块,由于系统中正好存在一个order 1的内

存块,所以直接用来分配

4 程序C申请一块大小为35K的内存,对应的order为0,同样由于系统中正好存在一个order 0的内存块,直接用来分

5 程序D申请一块大小为67K的内存,对应的order为1

5.1 系统中不存在order 1的内存块,于是将order 2的内存块分裂成两块order 1的内存块

5.2 找到order 1的内存块,进行分配

6 程序B释放了它申请的内存,即一个order 1的内存块

7 程序D释放了它申请的内存

7.1 一个order 1的内存块回收到内存当中

7.2由于该内存块的伙伴也是空闲的,因此两个order 1的内存块合并成一个order 2的内存块

8 程序A释放了它申请的内存,即一个order 0的内存块

9 程序C释放了它申请的内存

9.1 一个order 0的内存块被释放

9.2两个order 0伙伴块都是空闲的,进行合并,生成一个order 1的内存块m

9.3 两个order 1伙伴块都是空闲的,进行合并,生成一个order 2的内存块

9.4 两个order 2伙伴块都是空闲的,进行合并,生成一个order 3的内存块

9.5 两个order3伙伴块都是空闲的,进行合并,生成一个order 4的内存块

相关的数据结构

在前面的文章中已经简单的介绍过struct zone这个结构,对于每个管理区都有自己的struct zone,而struct zone中的struct free_area则是用来描述该管理区伙伴系统的空闲内存块的

<mmzone.h>

structzone{ … … … … }

<mmzone.h>

structfree_area{ };

free_area共有MAX_ORDER个元素,其中第order个元素记录了2^order的空闲块,这些空闲块在free_list中以双向链表的形式组织起来,对于同等大小的空闲块,其类型不同,将组织在不同的free_list中,nr_free记录了该free_area中总共的空闲内存块的数量。MAX_ORDER的默认值为11,这意味着最大内存块的大小为2^10=1024个页框。对于同等大小的内存块,每个内存块的起始页框用于链表的节点进行相连,这些节点对应的着struct page中的lru域

我想有一天和你去旅行。去那没有去过的地方,

Linux伙伴系统

相关文章:

你感兴趣的文章:

标签云: