memcache中管理內(nèi)存的數(shù)據(jù)結(jié)構(gòu)如下:
typedef struct {
unsigned int size; /* sizes of items */
unsigned int perslab; /* how many items per slab */

void **slots; /* list of item ptrs */
unsigned int sl_total; /* size of previous array */
unsigned int sl_curr; /* first free slot */

void *end_page_ptr; /* pointer to next free item at end of page, or 0 */
unsigned int end_page_free; /* number of items remaining at end of last alloced page */

unsigned int slabs; /* how many slabs were allocated for this class */

void **slab_list; /* array of slab pointers */
unsigned int list_size; /* size of prev array */

unsigned int killing; /* index+1 of dying slab, or zero if none */
} slabclass_t;

程序中有一個全局的數(shù)組
static slabclass_t slabclass[POWER_LARGEST + 1]用于保存slab,預(yù)分配內(nèi)存池時調(diào)用的是void slabs_init(const size_t limit, const double factor) 函數(shù),其中l(wèi)imit是內(nèi)存池的最大容量,factor是分配時的增長因子.
比方說,加入factor是2,第一個在slabclass數(shù)組中的slab的每個item大小是128字節(jié),那么下一個slab每個item的大小就是128*2,再下一個就是128*2*2(注意,為了簡化問題的說明,上面沒有考慮地址對齊的因素).
在預(yù)分配內(nèi)存池時,最多給每個slab保存item的容量是1M內(nèi)存,這個數(shù)值由#define POWER_BLOCK 1048576決定.
因此,slab中的幾個元素在預(yù)分配內(nèi)存時是這么定的:
size有一個起始值,這個值以后的增長由factor決定,增長的過程前面已經(jīng)闡述過了;
perslab保存的是一個slab存放的item數(shù)量,因此perslab = POWER_BLOCK / slabclass[i].size;
如果預(yù)先分配一段內(nèi)存供使用的話,也就是沒有定義DONT_PREALLOC_SLABS宏,那么就調(diào)用slabs_preallocate進行預(yù)分配內(nèi)存.
其中,end_page_ptr指向這個預(yù)分配好的指針,end_page_free表示的是目前空閑可用item的數(shù)量,在預(yù)分配時,這個值與perslab相同.
在這個內(nèi)存池模型中,每個page實際上是一個數(shù)組,數(shù)組中每個元素的大小就是這個slab中item的大小.
另外,slots保存的是釋放出來的item指針,sl_total表示總的數(shù)量,sl_curr表示的是目前可用的已經(jīng)釋放出來的item數(shù)量.
每一次要分配內(nèi)存的時候,首先根據(jù)需要分配的內(nèi)存大小在slabclass數(shù)組中查找索引最小的一個大于所要求內(nèi)存的slab,如果slots不為空,那么就從這里返回內(nèi)存,否則去查找end_page_ptr,如果也沒有,那么就只能返回NULL了.
每一次釋放內(nèi)存的時候,同樣的找到應(yīng)該返回內(nèi)存的slab元素,改寫前面提到的slot指針和sl_curr數(shù).
有點倉促,以后再完善~~