Nginx系列三 内存池的设计

时间:2023-03-10 01:52:36
Nginx系列三 内存池的设计

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开发从入门到精通