伙伴系统(buddy system),动态管理存储。
内存分成不同的zone 区域:DMA zone ,normal zone ,highmem zone 等;目前kernel 4.19 没有highmem zone 。
kernel-4.19/include/linux/mmzone.h
struct zone {
/* zone watermarks, access with *_wmark_pages(zone) macros */ unsigned long watermark[NR_WMARK];
#每个zone 对应的三个水位值,跟杀应用内存回收相关
long lowmem_reserve[MAX_NR_ZONES];
#highmem zone 内存不足会占用一部分normal zone ,normal zone 不足会占用一部分DMA zone #,所以对DMA zone 和 normal zone 都要预留一部分,避免被其它zone 占完。
#/proc/sys/vm # cat min_free_kbytes
....
struct free_area free_area[MAX_ORDER];
#空闲页管理,这里按照 2^n (n =0,...,11) 页大小管理空闲的页面
}
struct free_area {
struct list_head free_list[MIGRATE_TYPES];
unsigned long nr_free;
};
对应每种 2^n 页大小的空闲空间,将对应的空间分为下面的 MIGRATE_TYPES 中类型:
enum migratetype { 45 MIGRATE_UNMOVABLE, 46 MIGRATE_MOVABLE, 47 MIGRATE_RECLAIMABLE, 48#ifdef CONFIG_CMA
}
可以查看
/proc/zoneinfo
/proc/pagetypeinfo
/proc/buddyinfo (不同类型页面按 2^n 大小统计的页面数量)


/proc/meminfo
/proc/vmstat
内存统计信息
vmstat 命令查看系统内存、i/o、cpu 等资源使用情况

伙伴系统通过alloc_pages 分配物理页
kernel-4.19/include/linux/gfp.h
#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
gfp_mask 分配掩码,分为两类,一类zone modifiers ,自定从哪个zone 分配,比如_GFP_DMS 、__GFP_MOVABLE 等,由低4位确定;另一类是action modifiers,不限制从哪个zone 分配,但是会改变分配行为;另外一个参数指分配联系页面数 2^n;
如alloc_pages(GFP_KERNEL,order)
->...->_alloc_pages_modemask
这里会调用get_page_from_freelist 尝试分配物理页,如果失败就会调用__alloc_pages_slowpath
slab 将伙伴系统分配的页可以按字节再次分配