1. 程式人生 > >Nginx系列三 內存池的設計

Nginx系列三 內存池的設計

回收 poll 內存管理 剖析 內存池 pop 操作 dsm log

Nginx的高性能的是用非常多細節來保證,epoll下的多路io異步通知。階段細分化的異步事件驅動,那麽在內存管理這一塊也是用了非常大心血。上一篇我們講到了slab分配器,我們能夠能夠看到那是對共享內存的管理的優化。Nginx在進程內也實現了自己的內存池,目的在於降低內存碎片,降低向操作系統的申請次數,減低模塊開發難度。Nginx實現的內存池實際上非常easy:

Nginx內存池的管理是分大內存和小內存的,詳細說來。Nginx在向系統初始化內存池後,當我們調用ngx_palloc申請小內存後,再調用ngx_free() 內存池是不負責回收的,只在銷毀內存池時候一並銷毀。

可是我們在ngx_palloc申請大於4KB的內存時候當我們ngx_free()的時候內存池是否則回收的,這一點很合理和自然,內存池未來提高內存的利用度,須要處理大內存的回收和再利用。

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;
};

struct ngx_pool_large_s {
    ngx_pool_large_t     *next;      //大於4KB的內存管理(可回收再利用)
    void                 *alloc;
};

typedef struct {
    u_char               *last;
    u_char               *end; 
    ngx_pool_t           *next;          //管理內存池
    ngx_uint_t            failed;   //經驗值 查找失敗大於6次則又一次分配
} ngx_pool_data_t;

這三個數據結構構成了主要的內存池的主體.通過ngx_create_pool能夠創建一個內存池,通過ngx_palloc能夠從內存池中分配指定大小的內存。

能夠看到是內存池對於內存的管理是區分大內存和小內存的,實際上大於4KB的申請,實際上是終於調用了malloc直接申請。只是興許由Nginx的內存池來管理。

通常每個請求都有一個這樣的簡單獨立的內存池,Nginx為每個TCP請求分配一個內存池,自然也為每個HTTP請求分配一個內存池,在連接釋放後,銷毀內存池,同一歸還給操作系統。內存的分配管理消耗系統極少資源。總結一下內存池的優點:最大優點就是把多次向系統申請內存的 操作整合成一次。這大大降低了CPU的資源消耗。同一時候降低了內存碎片。
參考資料:《深入理解Nginx》 陶輝

《深入剖析Nginx》 高凱群

Nginx開發從入門到精通

Nginx系列三 內存池的設計