学习内存管理之前我们先了解几个重要的结构体,这些结构体理解了,基本对内存管理也就理解了一半。我说的。
struct zone {
unsigned long watermark[NR_WMARK];
struct pglist_data *zone_pgdat;
struct per_cpu_pageset __percpu *pageset;
struct free_area free_area[MAX_ORDER];
......
}
enum zone_watermarks {
WMARK_MIN,
WMARK_LOW,
WMARK_HIGH,
NR_WMARK
};
struct per_cpu_pageset {
struct per_cpu_pages pcp;
......
};
struct per_cpu_pages {
int count; /* number of pages in the list */
int high; /* high watermark, emptying needed */
int batch; /* chunk size for buddy add/remove */
struct list_head lists[MIGRATE_PCPTYPES];
};
struct free_area {
struct list_head free_list[MIGRATE_TYPES];
unsigned long nr_free;
};
enum migratetype {
MIGRATE_UNMOVABLE,
MIGRATE_MOVABLE,
MIGRATE_RECLAIMABLE,
MIGRATE_PCPTYPES, /* the number of types on the pcp lists */
MIGRATE_HIGHATOMIC = MIGRATE_PCPTYPES,
MIGRATE_CMA,
MIGRATE_ISOLATE, /* can't allocate from here */
MIGRATE_TYPES
};
typedef struct pglist_data {
struct zone node_zones[MAX_NR_ZONES];
struct zonelist node_zonelists[MAX_ZONELISTS];
enum zone_type kswapd_classzone_idx;
struct lruvec lruvec;
......
}
enum zone_type {
ZONE_DMA32,
ZONE_NORMAL,
ZONE_MOVABLE,
......
__MAX_NR_ZONES
};
struct lruvec {
struct list_head lists[NR_LRU_LISTS];
struct zone_reclaim_stat reclaim_stat;
atomic_long_t inactive_age;
unsigned long refaults;
};
enum lru_list {
LRU_INACTIVE_ANON = LRU_BASE,
LRU_ACTIVE_ANON = LRU_BASE + LRU_ACTIVE,
LRU_INACTIVE_FILE = LRU_BASE + LRU_FILE,
LRU_ACTIVE_FILE = LRU_BASE + LRU_FILE + LRU_ACTIVE,
LRU_UNEVICTABLE,
NR_LRU_LISTS
};
完了,看完这些结构体更糊涂了,别急,我们结合上篇文章的讲解把node, zone, page的组织关系和这些结构体串起来。
内核空间管理机制除了上面的伙伴算法,per-CPU页框高速缓存外,还有slab缓存,vmalloc机制。后面会一个一个详细说明。他们的区别如下:
1.伙伴算法:负责大块连续物理内存的分配和释放,以页框为基本单位。该机制可以避免外部碎片。
2.per-CPU页框高速缓存:内核经常请求和释放单个页框,该缓存包含预先分配的页框,用于满足本地CPU发出的单一页框请求。
3.slab缓存:负责小块物理内存的分配,并且它也作为高速缓存,主要针对内核中经常分配并释放的对象。
4.vmalloc机制:vmalloc机制使得内核通过连续的线性地址来访问非连续的物理页框,这样可以最大限度的使用高端物理内存。
下面一篇我们进入内存分配机制的基本单位——分区页框分配器(zoned page frame allocator)