前言
在SGI STL的内存池中,有小块内存和大块内存之分,分界线是128字节,因为这个内存池是给容器用的,所以比较小,而Nginx内存池的小块内存和大块内存分界线是一个页(4096字节)。。。下面介绍Nginx内存池的重要的类型定义和接口。
1. 宏定义
第一个宏就是可从内存池分配的最大内存,大小是page(4k) - 1,就是4096 - 1 (4095)。
第二个宏是默认内存池大小,为16k大小。
第三个宏是内存池内存分配的字节对齐数字。
/*
* NGX_MAX_ALLOC_FROM_POOL should be (ngx_pagesize - 1), i.e. 4095 on x86.
* On Windows NT it decreases a number of locked pages in a kernel.
*/
#define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1)
#define NGX_DEFAULT_POOL_SIZE (16 * 1024)
#define NGX_POOL_ALIGNMENT 16
下面这个宏表示内存池的最小大小,里面有个ngx_align,转到定义后,可看到一个似曾相识的宏,这和SGI STL的内存池的ROUND_UP()函数做同样的事情,就是把需要的内存上调置临近的16的倍数。
#define NGX_MIN_POOL_SIZE \
ngx_align((sizeof(ngx_pool_t) + 2 * sizeof(ngx_pool_large_t)), \
NGX_POOL_ALIGNMENT)
#define ngx_align(d, a) (((d) + (a - 1)) & ~(a - 1))
2.重要类型定义
主结构体类型定义
// 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; // 清理函数handler的入口指针
ngx_log_t *log;
};
小块内存数据头类型定义,主结构体的第一个成员 d就是该类型
typedef struct ngx_pool_s ngx_pool_t;
// 小块内存数据头信息
typedef struct {
u_char *last; // 可分配内存开始位置
u_char *end; // 可分配内存末尾位置
ngx_pool_t *next; // 保存下一个内存池的地址
ngx_uint_t failed; // 记录当前内存池分配失败的次数
} ngx_pool_data_t;
大块内存数据头类型定义
typedef struct ngx_pool_large_s ngx_pool_large_t;
// 大块内存类型定义
struct ngx_pool_large_s {
ngx_pool_large_t *next; // 下一个大块内存
void *alloc; // 记录分配的大块内存的起始地址
};
清理操作类型定义
typedef void (*ngx_pool_cleanup_pt)(void *data); // 清理回调函数的类型定义
typedef struct ngx_pool_cleanup_s ngx_pool_cleanup_t;
// 清理操作的类型定义,包括一个清理回调函数,传给回调函数的数据和下一个清理操作的地址
struct ngx_pool_cleanup_s {
ngx_pool_cleanup_pt handler; // 清理回调函数
void *data; // 传递给回调函数的指针
ngx_pool_cleanup_t *next; // 指向下一个清理操作
};
3. 重要函数接口
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); // 重置内存池
void *ngx_palloc(ngx_pool_t *pool, size_t size); // 内存分配函数,支持内存对齐
void *ngx_pnalloc(ngx_pool_t *pool, size_t size); // 内存分配函数,不支持内存对齐
void *ngx_pcalloc(ngx_pool_t *pool, size_t size); // 内存分配函数,支持内存初始化0
ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p // 内存释放(大块内存)
// 添加清理handler
ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size);