Nginx源码研究(7)——内存池结构ngx_pool_t
简介
本文主要介绍Nginx内存池结构ngx_pool_t
这一重要的数据结构的使用方法和具体实现。同时为了方便学习和研究,还从ngx_pool_t
抽取了一个完全独立的cg_pool_t
结构,不依赖Nginx,也不依赖任何第三方类库,可以直接将源码拿走集成进现有系统中。
典型的应用场景是这样的,假如你有一个nginx扩展,用到了ngx_pool_t这个数据结构,但是现在有一个需求是需要将这份扩展代码独立出来,不依赖nginx运行,那么这个cg_pool_t
是你的好帮手,你几乎只需要将头文件从ngx_palloc.h
换为cg_pool.h
即可,代码完全不用修改即可完成移植。
Nginx的内存池在大量的小块内存的申请和释放的时候,能更快地进行内存分配(对比malloc和free),同时减少内存碎片,防止内存泄露。尤其是在防止内存泄露方面,Nginx的内存池的设计可谓非常巧妙。调用者可以一直在一个ngx_pool_t
上调用ngx_palloc申请内存,而只需在最后释放这个ngx_pool_t
对象即可将中途所有申请的内存统统一块释放掉。从而大大减少内存泄露的可能性,也大大简化c程序的开发逻辑流程。
Nginx内存池源代码位置
src/core/ngx_palloc.{h,c}
cg_pool_t内存池的源码位置
https://github.com/zieckey/nginx-research/tree/master/libnginx/pool
源码分析
typedef struct ngx_pool_large_s ngx_pool_large_t;
//大内存结构
struct ngx_pool_large_s {
ngx_pool_large_t *next; //下一个大块内存
void *alloc;//nginx分配的大块内存空间
};
//该结构用来维护内存池的数据块,供用户分配之用
typedef struct {
u_char *last; //当前内存分配结束位置,即下一段可分配内存的起始位置
u_char *end; //内存池结束位置
ngx_pool_t *next; //链接到下一个内存池
ngx_uint_t failed;//统计该内存池不能满足分配请求的次数
} ngx_pool_data_t;
//该结构维护整个内存池的头部信息
struct ngx_pool_s {
ngx_pool_data_t d; //数据块
size_t max; //数据块大小,即小块内存的最大值
ngx_pool_t *current; //保存当前内存值
ngx_chain_t *chain; //可以挂一个chain结构
ngx_pool_large_t *large; //分配大块内存用,即超过max的内存请求
ngx_pool_cleanup_t *cleanup; //挂载一些内存池释放的时候,同时释放的资源
ngx_log_t *log;
};
内存结构图
测试代码
该测试代码的完整工程的编译和运行方式请参考 https://github.com/zieckey/nginx-research项目。Linux&Windows都测试通过。
TEST_UNIT(ngx_pool) {
ngx_pool_t* pool = ngx_create_pool(1024, NULL);
char* p = (char*)ngx_palloc(pool, 32);
const char* s = "hello world\n";
strcpy(p, s);
H_TEST_ASSERT(strcmp(p, s) == 0);
p = (char*)ngx_palloc(pool, 4096); // alloc a large block
ngx_destroy_pool(pool);
}
参考:
- 淘宝:Nginx开发从入门到精通 http://tengine.taobao.org/book/chapter_02.html#ngx-queue-t-100
- nginx源码注释 https://github.com/zieckey/nginx-1.0.14_comment/blob/master/src/core/ngx_palloc.h
- nginx源码注释 https://github.com/zieckey/nginx-1.0.14_comment/blob/master/src/core/ngx_palloc.c
- Nginx源码剖析之内存池,与内存管理 http://blog.csdn.net/v_july_v/article/details/7040425
- nginx源码学习—-内存池 http://www.cnblogs.com/xiekeli/archive/2012/10/17/2727432.html
- nginx源码研究 https://code.google.com/p/nginxsrp/wiki/NginxCodeReview