Nginx系列三 內存池的設計
阿新 • • 發佈:2017-05-23
回收 poll 內存管理 剖析 內存池 pop 操作 dsm log
這三個數據結構構成了主要的內存池的主體.通過ngx_create_pool能夠創建一個內存池,通過ngx_palloc能夠從內存池中分配指定大小的內存。
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系列三 內存池的設計