memcache中記憶體管理原始碼剖析

2021-06-08 09:05:10 字數 2482 閱讀 8537

memcahce採用了記憶體頁面,記憶體頁面上的記憶體塊技術實現了記憶體管理器,對item的指標採用了hashtable的方法,通過item的key值實現快速定位查詢item指標的方法,這裡詳細剖析一下實現的關鍵**.

首先是記憶體管理,在slabs.c**中實現.

(1).void slabs_init()

void slabs_init(const size_t limit, const double factor, const bool prealloc) else

(2).void slabs_preallocate():

#ifndef dont_prealloc_slabs

static void slabs_preallocate (const unsigned int maxslabs)

#endif

(3).int grow_slab_list():

//當乙個slab(記憶體頁面)用光後,又有新的item要插入這個id,那麼它就會重新申請新的slab,申請新的slab時,對應id的slab鍊錶就要增長,這個鍊錶是成倍增長的,

//在函式grow_slab_list函式中,這個鏈的長度從1變成2,從2變成4,從4變成8……

static int grow_slab_list (const unsigned int id)

return 1;

}(4). int do_slabs_newslab()

//該函式分配乙個新的記憶體頁,每個slabclass_t會有多個頁面

static int do_slabs_newslab(const unsigned int id)

(5). void *do_slabs_alloc()

//記憶體單元:集合中維護的"邏輯記憶體塊"的大小,它是以8位元組對齊的

//記憶體頁:  slabclass_t分配記憶體的時候是以perslab個記憶體單元分配的,這perslab個連續的記憶體單元就是記憶體頁

//slabs_alloc是乙個巨集,對於多執行緒模式和單執行緒模式,它會對映到不同的函式

void *do_slabs_alloc(const size_t size, unsigned int id) else if (p->sl_curr != 0) else else else

(6). void do_slabs_free()

void do_slabs_free(void *ptr, const size_t size, unsigned int id)

(7). void *memory_allocate()

//從mem_base中分配size大小的記憶體

static void *memory_allocate(size_t size) else else

然後是通過item的key值實現快速定位item指標位址的hashtabel,在assoc.c中。

(1). void assoc_init()

/*hashtable的初始化,計算hashtable的大小-->分配空間-->初始化空間為null*/

//分配hashtable的所需的記憶體

void assoc_init(void)

(2). item *assoc_find()

//根據鍵尋找對應的值

item *assoc_find(const char *key, const size_t nkey) else

(3). item** _ha****em_before()

//尋找key對應的元素的指標變數的位址

static item** _ha****em_before (const char *key, const size_t nkey) else

(4). void assoc_expand()

static void assoc_expand(void) else

(5). void do_assoc_move_next_bucket()

//被static void conn_set_state()呼叫

void do_assoc_move_next_bucket(void)

old_hashtable[expand_bucket] = null;

expand_bucket++;

//對於其他的元素的遷移會在使用者使用者請求的時候進行移動,這是把時間消耗分散的延遲處理方式,當元素遷移完成後,

//就會釋放舊的hashtable占用的資源free

if (expand_bucket == hashsize(hashpower - 1))

(6). int assoc_insert()

//將item加入到hashtable中

int assoc_insert(item *it) else

(7). void assoc_delete()

//從hashtable中刪除對應key的item

void assoc_delete(const char *key, const size_t nkey)

Memcache記憶體管理

在不斷malloc和free操作,會形成很小的記憶體的片段,我們無法繼續利用。slab allocator機制 將記憶體劃分為數個slab class倉庫 各個倉庫切分成不同尺寸的小塊 chunk 需要存放內容的時候,需要先判斷內容的大小,為期選擇合理的倉庫存放 memcache儲存著slab cl...

memcache 記憶體管理

page為記憶體分配的最小單位 memcached 的記憶體分配以page為單位,預設情況下乙個page是1m slabs劃分資料空間 memcached 並不是將所有大小的資料都放在一起的,而是預先將資料空間劃分為一系列slabs,每個slab只負責一定範圍內的資料儲存。每個slab負責的空間其實...

memcache的記憶體管理機制

memcache使用了slab allocator的記憶體分配機制 按照預先規定的大小,將分配的記憶體分割成特定長度的塊,以 完全解決記憶體碎片問題 memcache的儲存涉及到slab,page,chunk三個概念 1 chunk為固定大小的記憶體空間,預設為96byte。2 page對應實際的物...