解读nginx内存池的设计与实现
内存相关的几个数据结构
内存池头部结构
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; //分配日志记录 };
内存池内容结构
typedef struct { u_char *last; //可分配内存的地址 u_char *end; //内存池的边界 ngx_pool_t *next; //下一块内存池 ngx_uint_t failed; //分配失败的次数 } ngx_pool_data_t;
大块内存结构
struct ngx_pool_large_s { ngx_pool_large_t *next; //指向下一个大块内存 void *alloc;//指向本块的大块内存 }; //next是从内存池的头部连接的一个单链表指针 //next是在内存池中分配的小内存,组成一个单链表把大块内存连接起来 //alloc是指向大块内存的内存地址
pool结构
nginx内存池是以单链表的形式管理的,其中只有在链表头,也就是第一个pool中有关于ngx_pool_t
字段的记录,其余节点都只有ngx_pool_data_t
字段,内存池的可用内存是ngx_pool_data_t
中的last
和end
来记录的。头结点中的ngx_pool_t
字段会记录关于large
页的管理链,和清理管理链cleanup
。
有关资源清理的设计
nginx清理cleanup这个结构设计为通用行的,每一个需要清理的资源节点都对应的有自己的clean handler,所以,可以使用这一套清理框架来设计自己的清理逻辑。
/*
* 分配一个可以用于回调函数清理内存块的内存
*/
ngx_pool_cleanup_t *
ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
{
ngx_pool_cleanup_t *c;
//分配一个ngx_pool_cleanup_t
c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
if (c == NULL) {
return NULL;
}
if (size) {
//分配一个data成员的内存
c->data = ngx_palloc(p, size);
if (c->data == NULL) {
return NULL;
}
} else {
c->data = NULL;
}
//handler是清理的回调函数
c->handler = NULL;
c->next = p->cleanup;
p->cleanup = c;
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);
return c;
}
ngx_pool_t中的cleanup字段管理着一个特殊的链表,该链表的每一项都记录着一个特殊的需要释放的资源。
对于这个链表中每个节点所包含的资源如何去释放,是自说明的。这也就提供了非常大的灵活性。
意味着,ngx_pool_t不仅仅可以管理内存,通过这个机制,也可以管理任何需要释放的资源
相关文章
- app多版本的服务端部署
背景 手机客户端按一定周期发版,但是客户不一定会及时更新到最新版本,所以需要服务端能支持旧版手机客户端。 服务端支持旧版手机客户端的方式主要有: 相同的接口支持不同版本手机端的请求,需要服务端接口
- 反向代理时URI的处理
当使用proxy_pass的时候,请求的URI传递给服务器是有一定的规则的。 proxy_pass带有URI 比如下面的配置: location /name/ { proxy_pass htt
- nginx-echo-命令引发的探索
起因 最初在 nginx.conf 中调试时,当时希望 echo 出对应的变量值,并没有成功。起初认为是 nginx 安装时,并没有安装 echo 模块,然而事后发现实际用的是 openresty,o
- nginx499状态码产生的原因
什么是 nginx 的 499 499 是 nginx 扩展的 4xx 错误,目的只是用于记录,并没有实际的响应。看一下 nginx 源码 ngx_http_request.h 对 499 的定义:
- Nginx配置文件参数说明
定义Nginx运行的用户和用户组 user www www; nginx进程数,建议设置为等于CPU数量*核数。 worker_processes 8; 全局错误日志定义类型,[ debug |
随机推荐
- app多版本的服务端部署
背景 手机客户端按一定周期发版,但是客户不一定会及时更新到最新版本,所以需要服务端能支持旧版手机客户端。 服务端支持旧版手机客户端的方式主要有: 相同的接口支持不同版本手机端的请求,需要服务端接口
- 反向代理时URI的处理
当使用proxy_pass的时候,请求的URI传递给服务器是有一定的规则的。 proxy_pass带有URI 比如下面的配置: location /name/ { proxy_pass htt
- nginx-echo-命令引发的探索
起因 最初在 nginx.conf 中调试时,当时希望 echo 出对应的变量值,并没有成功。起初认为是 nginx 安装时,并没有安装 echo 模块,然而事后发现实际用的是 openresty,o
- nginx499状态码产生的原因
什么是 nginx 的 499 499 是 nginx 扩展的 4xx 错误,目的只是用于记录,并没有实际的响应。看一下 nginx 源码 ngx_http_request.h 对 499 的定义:
- Nginx配置文件参数说明
定义Nginx运行的用户和用户组 user www www; nginx进程数,建议设置为等于CPU数量*核数。 worker_processes 8; 全局错误日志定义类型,[ debug |