ngx_pool_t
定義在 src/core/ngx_core.h
typedef struct ngx_pool_s ngx_pool_t;
ngx_pool_s
定義在 src/core/ngx_palloc.h
struct ngx_pool_s {ngx_pool_data_t d;size_t max;ngx_pool_t *current;ngx_chain_t *chain;ngx_pool_large_t *large;ngx_pool_cleanup_t *cleanup;ngx_log_t *log; };
ngx_pool_s
的主要作用是實現一個內存池(memory pool) ,為 Nginx 提供高效、低開銷的內存分配和釋放機制。它的設計目標包括:
- 減少頻繁調用系統級的內存分配函數(如
malloc
和free
),從而提高性能。- 簡化內存釋放:當內存池不再使用時,只需一次性釋放整個內存池,而不需要逐個釋放每個小塊內存。
- 支持大塊內存分配(通過
large
字段)和清理回調(通過cleanup
字段)。
struct ngx_pool_s {ngx_pool_data_t d; // 當前內存池的數據塊信息size_t max; // 小塊內存的最大分配大小ngx_pool_t *current; // 指向當前內存池鏈表中的某個節點ngx_chain_t *chain; // 鏈表,用于管理緩沖區鏈ngx_pool_large_t *large; // 大塊內存分配鏈表ngx_pool_cleanup_t *cleanup; // 清理回調鏈表ngx_log_t *log; // 日志對象,用于記錄錯誤信息 };
ngx_pool_data_t
在 src\core\ngx_palloc.h
typedef struct {u_char *last;u_char *end;ngx_pool_t *next;ngx_uint_t failed; } ngx_pool_data_t;
last
: 指向當前內存塊中未分配內存的起始位置。每次分配內存時,從last
開始分配,并更新last
。end
: 指向當前內存塊的末尾位置。如果last
超過end
,表示當前內存塊已滿,需要分配新的內存塊。next
: 指向下一個內存塊。Nginx 的內存池是由多個內存塊組成的鏈表。failed
: 記錄分配失敗的次數。如果某個內存塊的分配失敗次數過多,Nginx 會跳過該內存塊,直接嘗試分配新的內存塊。
ngx_pool_large_t?
定義在??src\core\ngx_palloc.h
typedef struct ngx_pool_large_s ngx_pool_large_t;struct ngx_pool_large_s {ngx_pool_large_t *next;void *alloc; };
next
- 類型:
ngx_pool_large_t *
- 含義:指向下一個
ngx_pool_large_s
節點的指針。- 作用:
ngx_pool_large_s
使用單向鏈表的形式組織所有分配的大塊內存。通過next
指針,可以遍歷整個鏈表,方便管理和釋放這些大塊內存。
alloc
- 類型:
void *
- 含義:指向實際分配的大塊內存的指針。
- 作用:
alloc
存儲了通過系統調用(如malloc
)分配的大塊內存的地址。Nginx 在需要釋放內存池時,可以通過遍歷鏈表并逐個釋放這些大塊內存。
大塊內存分配流程
當請求的內存超過閾值時:
- 調用?
ngx_alloc
?從系統分配所需內存。- 創建?
ngx_pool_large_s
?節點,alloc
?指向新分配的內存。- 將新節點插入鏈表
內存池結構關系
pool[ngx_pool_t] -->|large| large1[ngx_pool_large_t]large1 -->|next| large2[ngx_pool_large_t]large2 -->|next| large3[ngx_pool_large_t]large3 -->|next| NULLlarge1 --> alloc1[Alloc Memory]large2 --> alloc2[Alloc Memory]large3 --> alloc3[Alloc Memory]
內存池 (ngx_pool_t) │ ├── ... 其他成員 ... │ └── large → [large_node1] → [large_node2] → ... → NULL│ │ │alloc alloc alloc↓ ↓ ↓[Memory1] [Memory2] [Memory3]