Linux Slab分配器(一)--概述
Linux Slab分配器(一)--概述
slab分配器是Linux内存管理中非常重要和复杂的一部分,其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内碎片,而且处理速度也太慢。而slab分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统。slab分配对象时,会使用最近释放的对象内存块,因此其驻留在CPU高速缓存的概率较高。
相关阅读:Linux Slab分配器(二)--初始化
用于描述和管理cache的数据结构是struct kmem_cache
- struct kmem_cache {
- /* 1) per-cpu data, touched during every alloc/free */
- /*per-CPU数据,记录了本地高速缓存的信息,也用于跟踪最近释放的对象,每次分配和释放都要直接访问它*/
- struct array_cache *array[NR_CPUS];
- /* 2) Cache tunables. Protected by cache_chain_mutex */
- unsigned int batchcount; /*本地高速缓存转入或转出的大批对象数量*/
- unsigned int limit; /*本地高速缓存中空闲对象的最大数目*/
- unsigned int shared;
- unsigned int buffer_size;/*管理对象的大小*/
- u32 reciprocal_buffer_size;/*buffer_size的倒数值*/
- /* 3) touched by every alloc & free from the backend */
- unsigned int flags; /* 高速缓存的永久标识*/
- unsigned int num; /* 一个slab所包含的对象数目 */
- /* 4) cache_grow/shrink */
- /* order of pgs per slab (2^n) */
- unsigned int gfporder; /*一个slab包含的连续页框数的对数*/
- /* force GFP flags, e.g. GFP_DMA */
- gfp_t gfpflags; /*与伙伴系统交互时所提供的分配标识*/
- size_t colour; /* 颜色的个数*/
- unsigned int colour_off; /* 着色的偏移量 */
- /*如果将slab描述符存储在外部,该指针指向存储slab描述符的cache,
- 否则为NULL*/
- struct kmem_cache *slabp_cache;
- unsigned int slab_size; /*slab管理区的大小*/
- unsigned int dflags; /*动态标识*/
- /* constructor func */
- void (*ctor)(void *obj); /*创建高速缓存时的构造函数指针*/
- /* 5) cache creation/removal */
- const char *name; /*高速缓存名*/
- struct list_head next; /*用于将高速缓存链入cache chain*/
- /* 6) statistics */
- #ifdef CONFIG_DEBUG_SLAB /*一些用于调试用的变量*/
- unsigned long num_active;
- unsigned long num_allocations;
- unsigned long high_mark;
- unsigned long grown;
- unsigned long reaped;
- unsigned long errors;
- unsigned long max_freeable;
- unsigned long node_allocs;
- unsigned long node_frees;
- unsigned long node_overflow;
- atomic_t allochit;
- atomic_t allocmiss;
- atomic_t freehit;
- atomic_t freemiss;
- /*
- * If debugging is enabled, then the allocator can add additional
- * fields and/or padding to every object. buffer_size contains the total
- * object size including these internal fields, the following two
- * variables contain the offset to the user object and its size.
- */
- int obj_offset;
- int obj_size;
- #endif /* CONFIG_DEBUG_SLAB */
- /*
- * We put nodelists[] at the end of kmem_cache, because we want to size
- * this array to nr_node_ids slots instead of MAX_NUMNODES
- * (see kmem_cache_init())
- * We still use [MAX_NUMNODES] and not [1] or [0] because cache_cache
- * is statically defined, so we reserve the max number of nodes.
- */
- /*struct kmem_list3用于组织该高速缓存中的slab*/
- struct kmem_list3 *nodelists[MAX_NUMNODES];
- /*
- * Do not add fields after nodelists[]
- */
- };
- struct kmem_list3 {
- struct list_head slabs_partial;/*slab链表,包含空闲对象和已分配对象的slab描述符*/
- struct list_head slabs_full; /*slab链表,只包含非空闲的slab描述符*/
- struct list_head slabs_free; /*slab链表,只包含空闲的slab描述符*/
- unsigned long free_objects; /*高速缓存中空闲对象的个数*/
- unsigned int free_limit; /*空闲对象的上限*/
- unsigned int colour_next; /*下一个slab使用的颜色*/
- spinlock_t list_lock;
- struct array_cache *shared; /* shared per node */
- struct array_cache **alien; /* on other nodes */
- unsigned long next_reap; /* updated without locking */
- int free_touched; /* updated without locking */
- };
|
评论暂时关闭