Nginx原始碼剖析 記憶體池結構ngx pool t

2021-07-28 10:24:18 字數 2632 閱讀 9856

struct ngx_pool_s;

ngx_pool_data_t

結構:該結構就是包含了操作該記憶體池的資料的一些指標

typedef   struct  ngx_pool_data_t;

ngx_pool_large_t

結構:表示大塊記憶體

struct  ngx_pool_large_s{

ngx_pool_large_t  *next;//指向下一塊大塊記憶體

void *alloc;//指向分配的大塊記憶體

ngx_pool_cleanup_t結構:這個結構用來表示記憶體池中的資料的清理handler。

struct ngx_pool_cleanup_s{

ngx_pool_cleanup_pt  handler;//表示清理函式

void*data;                                    //表示傳遞給清理函式的資料

ngx_pool_cleanup_t*next;     //表示下乙個清理handler

當destroy這個pool的時候會遍歷清理handler鍊錶,然後呼叫handler;

建立記憶體池---------ngx_create_pool();

銷毀記憶體池 -------ngx_destroy_pool()和ngx_pfree()//ngx_pfree函式只釋放large鍊錶中申請的記憶體,普通記憶體有destroy函式統一釋放

重置記憶體池------ngx_reset_pool()

分配記憶體-------1.void *ngx_palloc(ngx_pool_t *pool,size_t  size);//建立乙個資料區為size的記憶體池

2.void *ngx_pnalloc(ngx_pool_t*pool,size_t size);//不進行記憶體對齊

3.void *ngx_pcalloc(ngx_pool_t*pool,size_t  size);//將分配的記憶體空間初始化

4.void *ngx_pmemalign(ngx_pool_t *pool,size_t size,size_t alignment);//返回乙個基於alignment大小size的記憶體空間,位址為alignment整數倍,     alignment為2的冪

記憶體分配返回值為分配的記憶體起始位址,函式中封裝了最基本的記憶體分配函式,

如free/malloc/memalign/posix_memalign分別被封裝為ngx_free;ngx_alloc/ngx_calloc;ngx_menalign;

1.建立記憶體池:

注:在ngx_max_alloc_from_pool(ngx_pagesize-1)中,ngx_pagesize = getpagesize(),getpagesize()函式功能是取得記憶體分頁的大小;

2.記憶體分配

nginx中對記憶體的管理分為大塊記憶體和小塊記憶體,當某乙個申請記憶體大於max就從大記憶體分配空間,否則從小塊記憶體中分配,nginx記憶體池在建立時就設定好了大小,

在以後分配小塊記憶體時,如果記憶體不夠,重新建立一塊小記憶體鏈結到記憶體池,當要分配大塊記憶體,則是在記憶體池外再分配空間進行管理。

(2)ngx_palloc_block的實現,這個函式功能是重新分配一塊記憶體池,然後鏈結到當前記憶體池的資料區指標,new的這個記憶體池大小和它的父記憶體池一樣大

注:該函式分配一塊記憶體之後,last指標指向ngx_pool_data結構之後資料區的起始位置,而建立記憶體池時,last指標指向ngx_pool_t結構體之後。

為什麼要這樣設定current,主要原因是在ngx_palloc中分配記憶體是從current開始,而這裡就是設定current為比較新分配的記憶體,當failed大於4說明我們至少請求了4次記憶體分配,都不能滿足我們的請求,此時我們就假設老的記憶體已經沒有空間,從新的記憶體開始。

(3)ngx_palloc_large,這個函式也是很簡單的malloc一塊ngx_pool_large_t然後鏈結到主的記憶體池上。直接在系統堆中分配一塊size

空間,查詢乙個large區,將分配的空間交給它;將large鏈結到記憶體池。

(4)記憶體池重置ngx_reset_pool():作用釋放大塊記憶體,重置所有的小塊記憶體

不理解:為什麼在重置小塊記憶體時,last要指向ngx_pool_t後邊而不是ngx_pool_data_t;

STL原始碼剖析 記憶體池的實現

2019年3月15日 3月23日,大概花了8天的時間,終於將sgi stl版本實現的記憶體池看懂了。不過記憶體池這個知識點大概在2018年8月份的時候就已經接觸了,今天終於弄懂了,如卸心中之塊壘!在此 的一些點,可能非常表面,如果需要深入了解,建議直接閱讀 stl原始碼剖析 侯捷 相應章節。記憶體池...

MySQL記憶體池結構原始碼 my alloc h

mysql使用記憶體池結構,理解該結構挺簡單的,但是對於my alloc.c中的分配過程感覺上很難理解。data structures for mysys my alloc.c root memory allocator ifndef my alloc h define my alloc h def...

Nginx 原始碼閱讀筆記1 記憶體池

在大體看完 unp 後本來想練手寫乙個小型 http 伺服器的,但是感覺少了點什麼,所以打算先學習一下 nginx 原始碼,看看大牛們是怎麼設計的。然而突然發現自己好像不怎麼了解 nginx,所以花了乙個多星期翻完了 深入理解 nginx 感興趣的部分,加強了對 nginx 的了解。計畫是以 lin...