- NGinx内存池主要结构体说明
主要说明内存池相关结构体的字段内容说明。
struct ngx_pool_cleanup_s {
ngx_pool_cleanup_pt handler;/* 清理的回调函数一般是ngx_pool_cleanup_file和ngx_pool_delete_file */
void *data; /* 指向存储的数据地址一般是ngx_pool_cleanup_file_t */
ngx_pool_cleanup_t *next;/* 下一个ngx_pool_cleanup_t */
};
typedef struct ngx_pool_large_s ngx_pool_large_t;
struct ngx_pool_large_s {
ngx_pool_large_t *next; /* 指向下一个存储地址 通过这个地址可以知道当前块长度 */
void *alloc; /* 数据块指针地址 */
};
typedef struct {
u_char *last;/* 内存池中未使用内存的开始节点地址 */
u_char *end; /* 内存池的结束地址 */
ngx_pool_t *next;/* 指向下一个内存池 */
ngx_uint_t failed;/* 失败次数,主要用于记录current后面内存池挂接的数量 考虑查找性能*/
} ngx_pool_data_t;
struct ngx_pool_s {
ngx_pool_data_t d; /* 内存池的数据区域*/
size_t max; /* 最大每次可分配内存 */
ngx_pool_t *current; /* 指向当前的内存池指针地址。ngx_pool_t链表上最后一个缓存池结构*/
ngx_chain_t *chain; /* 缓冲区链表 */
ngx_pool_large_t *large; /* 存储大数据的链表 malloc申请内存需要注意内存释放*/
ngx_pool_cleanup_t *cleanup; /* 可自定义回调函数, 结构体及数据
data都是在内存池上申请,无需注意内存的释放*/
ngx_log_t *log; /* 日志 */
};
typedef struct {
ngx_fd_t fd; /*文件描述符*/
u_char *name;/*文件的存储路径*/
ngx_log_t *log; /*log日志记录文件*/
} ngx_pool_cleanup_file_t;
数据结构图
1. Nginx的内存池会放在ngx_pool_t的数据结构上(ngx_pool_data_t用于记录内存块block的可用地址空间和内存块尾部)。当初始化分配的内存块大小不能满足需求的时候,Nginx就会调用ngx_palloc_block函数来分配一个新的内存块ngx_pool_t,通过链表的形式连接起来。内存池只有全部销毁的函数ngx_destroy_pool,没有针对单个内存的释放函数。
当申请的内存大于pool->max的值的时候,Nginx就会单独分配一块large的内存块,会放置在pool->large的链表结构上。ngx_pool_large_t本身的内存空间是在内存池上申请的,无需注意释放。但是alloc数据块的内存直接malloc申请,关注内存释放。
pool->cleanup的链表结构主要存放需要通过回调函数关闭文件描述符及删除文件。ngx_pool_cleanup_s本身结构体的空间是在内存池上申请的;结构体成员data也是在内存池上申请的,无需考虑释放。
主要函数说明
1、内存池的申请、销毁及重设
疑问:1、内存池只有全部销毁及重设操作,如果频繁在内存池上申请内存,而不释放?
2、内存池是如何工作的?
/*主要完成内存池首个节点的初始化工作。*/
ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);
/*主要完成内存池中挂接所有数据的释放,及内存池链表的数据释放*/
void ngx_destroy_pool(ngx_pool_t *pool);
/*应该是内存池数据不再使用时刻重新设置*/
void ngx_reset_pool(ngx_pool_t *pool);
2、从内存池上申请内存,或者大块malloc内存的申请及释放
/*按照字节对其方式,在内存上申请size大小内容*/
void *ngx_palloc(ngx_pool_t *pool, size_t size);
/*按照非字节对其方式,在内存上申请size大小内容*/
void *ngx_pnalloc(ngx_pool_t *pool, size_t size);
/*按照字节对其方式,在内存上申请size大小内容并对申请内存进行初始化操作*/
void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
/*申请大块内存地址,且挂在内存池*/
void *ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment);
/*释放指定的大块内存地址*/
ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);