1,伙伴系统的作用:
伙伴系统主要是为了高效使用物理内存,尽量减少内存碎片的产生
2,伙伴系统的概念:
系统中的内存总是两两分组,每组中的两个内存块称为伙伴
3,伙伴系统的原理:
伙伴系统是相对于struct zone而言,将每个zone的空闲内存分为最多11个数组,比如第一个数组里管理着2^0页的内存,所有这些2^0的页以struct page的lru域的双向链表相连接,第二个数组管理着2^1页的内存,所有这些2^0的页以struct page的lru域的双向链表相连接,以此类推,。。。。。当要申请一个4k(即2^0页)的内存时,则直接从第一个数组申请,如果第一个数组没有空闲内存,则将第二个数组的2^1的页分解为两个2^0的页以供申请。
4,伙伴系统的相关数据结构
伙伴系统是相对于struct zone而言的,struct zone中的struct free_area是用来描述该管理区伙伴系统的空闲内存块的,
struct zone { ... ... struct free_area free_area[MAX_ORDER]; ... ... } struct free_area { struct list_head free_list[MIGRATE_TYPES]; unsigned long nr_free; //该free_area中总共的空闲内存块的数量,单位为页大小 }; #define MAX_ORDER 11 #define MIGRATE_TYPES 5
5,防止内存碎片相关:
用户空间的程序不会碰到内存碎片的问题,因为其内存是通过页表映射的,无论空闲页在物理内存的分配如何,应用程序
看到的内存总是连续的。但是对于内核来说,会经常碰到内存碎片的问题,因为大部分物理内存是线性映射到内核空间的。
内核将页分为以下三种类型
不可移动页:在内存中有固定位置,不能移动到其它位置。
可回收页:不能直接移动,但是其内存可以回收。kswapd守护进程会周期性的回收可回收页的内存。
可移动页:页可以随意移动,用户空间应用程序的页属于这个类型,属于页表映射的
#define MIGRATE_UNMOVABLE 0 #define MIGRATE_RECLAIMABLE 1 #define MIGRATE_MOVABLE 2 #define MIGRATE_PCPTYPES 3 /* the number of types on the pcp lists */ #define MIGRATE_RESERVE 3 #define MIGRATE_ISOLATE 4 /* can't allocate from here */ #define MIGRATE_TYPES 5
MIGRATE_PCPTYPES是per_cpu_pageset,即用来表示每CPU页框高速缓存的数据结构中的链表的迁移类型数目
MIGRATE_RESERVE是在前三种的列表中都没用可满足分配的内存块时,就可以从MIGRATE_RESERVE分配
MIGRATE_ISOLATE用于跨越NUMA节点移动物理内存页,在大型系统上,它有益于将物理内存页移动到接近于是用该页最频繁地CPU
MIGRATE_TYPES表示迁移类型的数目
当一个指定的迁移类型所对应的链表中没有空闲块时,将会按以下定义的顺序到其他迁移类型的链表中寻找
static int fallbacks[MIGRATE_TYPES][MIGRATE_TYPES-1] = { [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE }, [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE }, [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE }, [MIGRATE_RESERVE] = { MIGRATE_RESERVE, MIGRATE_RESERVE, MIGRATE_RESERVE }, /* Never used */ };
6,debug相关:
有关伙伴系统的当前状态信息可以在/proc/buddyinfo中获取。