Linux Slub分配器(一)--概述

水平有限,描述不當之處還請之處,轉載請註明出處http://blog.csdn.net/vanbreaker/article/details/7694648   

       Slab分配器一直處於內核內存管理的核心地位,儘管如此,它還是擁有自身的缺點,最明顯的兩點就是複雜性和過多的管理數據造成的內存上的開銷。針對這些問題,linux引入了slub分配器,slub分配器保留了slab分配器的所有接口,實際上slub分配器的模型和slab分配的模型是基本一致的,只不過在一些地方進行了精簡,這也使得slub分配器工作起來更爲遊刃有餘。兩者主要的區別如下:

  • slab分配器爲了增加分配速度,引入了一些管理數組,如slab管理區中的kmem_bufctl數組和緊隨本地CPU結構後面的用來跟蹤最熱空閒對象的數組,這些結構雖然加快了分配對象的速度,但也增加了一定的複雜性,而且隨着系統變得龐大,其對內存的開銷也越明顯。而slub分配器則完全摒棄了這些管理數據,個人覺得這也是slub分配器最精髓的地方,至於slub分配器的具體做法是怎樣的,後面再做分析;
  • slab分配器針對每個緩存,根據slab的狀態劃分了3個鏈表--full,partial和free. slub分配器做了簡化,去掉了free鏈表,對於空閒的slab,slub分配器選擇直接將其釋放;
  • slub分配器摒棄了slab分配器中的着色概念,在slab分配器中,由於顏色的個數有限,因此着色也無法完全解決slab之間的緩存行衝突問題,考慮到着色造成了內存上的浪費,slub分配器沒有引入着色;
  • 在NUMA架構的支持上,slub分配器也較slab分配器做了簡化。

下面來看slub分配器涉及到的主要數據結構

緩存描述結構:

struct kmem_cache {
	/* Used for retriving partial slabs etc */
	unsigned long flags; /* cache屬性的描述標識 */
	int size;	     /* 分配給對象的內存大小,可能大於實際對象的大小 */
	int objsize;	     /* 對象的實際大小 */	
	int offset;          /* 存放空閒對象的偏移,以字節爲單位 */
	struct kmem_cache_order_objects oo;/* oo用來存放分配給slab的頁框的階數(高16位)和
	                                            slab中的對象數量(低16位) */

	/*
	 * Avoid an extra cache line for UP, SMP and for the node local to
	 * struct kmem_cache.
	 */
	struct kmem_cache_node local_node;/* 本地節點的slab信息 */

	/* Allocation and freeing of slabs */
	struct kmem_cache_order_objects max;
	struct kmem_cache_order_objects min;
	gfp_t allocflags;      /* 分配時用的GFP標識 */
	int refcount;	       /* 緩存中存在的對象種類數目,因爲slub允許緩存複用,
	                              因此一個緩存中可能存在多種對象類型 */
	void (*ctor)(void *);  /* 創建對象的構造函數 */
	int inuse;             /* 元數據的偏移 */
	int align;	       /* 對齊值 */
	unsigned long min_partial;/* partial slab鏈表中的最小slab數目 */
	const char *name;	  /* 緩存名 */
	struct list_head list;    /* 用於將緩存鏈入slab_caches全局緩存鏈表 */
#ifdef CONFIG_SLUB_DEBUG
	struct kobject kobj;      /* For sysfs */
#endif

#ifdef CONFIG_NUMA
	/*
	 * Defragmentation by allocating from a remote node.
	 */
	int remote_node_defrag_ratio;   /* 該值越小,越傾向於從本節點分配對象 */
	struct kmem_cache_node *node[MAX_NUMNODES];/* NUMA架構下每個節點對應的slab信息 */
#endif
#ifdef CONFIG_SMP
	struct kmem_cache_cpu *cpu_slab[NR_CPUS];  /* SMP系統下每個CPU對應的slab信息 */
#else
 	struct kmem_cache_cpu cpu_slab; /* 單核系統下CPU對應的slab信息 */
#endif
};


節點的slab信息描述結構:

struct kmem_cache_node {
	spinlock_t list_lock;       /* Protect partial list and nr_partial */
	unsigned long nr_partial;   /* partial slab鏈表中slab的數量 */
	struct list_head partial;   /* partial slab鏈表表頭*/
#ifdef CONFIG_SLUB_DEBUG
	atomic_long_t nr_slabs;      /* 節點中的slab數 */
	atomic_long_t total_objects; /* 節點中的對象數 */
	struct list_head full;       /* full slab鏈表表頭 */
#endif
};


 

本地CPU的slab信息描述結構:

struct kmem_cache_cpu {
	void **freelist;	/* 指向本地CPU的第一個空閒對象 */
	struct page *page;	/* 分配給本地CPU的slab的頁框 */
	int node;	        /* 頁框所處的節點,值爲-1時表示DEBUG */
	unsigned int offset;	/* 空閒對象指針的偏移,以字長爲單位 */
	unsigned int objsize;	/* 對象的大小 */
#ifdef CONFIG_SLUB_STATS
	unsigned stat[NR_SLUB_STAT_ITEMS];/*用以記錄slab的狀態*/
#endif
};


 

用下圖可以描述這些slub分配器的核心數據結構之間的關係

 

至此已大概介紹了slub分配器的一些概念和涉及到的核心數據結構,具體的實現細節和原理在後面分析各個部分的代碼時再做交代!

 

發佈了59 篇原創文章 · 獲贊 33 · 訪問量 50萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章