Nginx内存池源码刨析
重要成员定义
主要的宏定义
// 在内存池中最大可分配内存 4096 4K
// nginx将小于4k的进行小内存管理
#define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1)
// 默认内存池的大小 16k
#define NGX_DEFAULT_POOL_SIZE (16 * 1024)
// 内存对齐
#define NGX_POOL_ALIGNMENT 16
// 内存池最小字节数,使用内存提升函数,
#define NGX_MIN_POOL_SIZE
\ ngx_align((sizeof(ngx_pool_t) + 2 *
\ sizeof(ngx_pool_large_t)),NGX_POOL_ALIGNMENT)
主要的结构体定义
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; // 连接内存池指针
ngx_pool_large_t *large; // 大内存指针,大于4k
ngx_pool_cleanup_t *cleanup; // 清理内存的指针
ngx_log_t *log; // 日志
}; // 内存池详细信息
// ngx_pool_t 就是 ngx_pool_s 类型
重要的辅助宏函数
这两个宏函数是用于内存提成的,和SGI STL中sound_up函数实现一样【SGI STL内存池源码刨析】
// 将d提升为a的整数倍
#define ngx_align(d, a) (((d) + (a - 1)) & ~(a - 1))
#define ngx_align_ptr(p, a)
\(u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
重要函数实现
创建内存池函数
ngx_create_pool函数
ngx_pool_t* ngx_create_pool(size_t size, ngx_log_t *log)
{
ngx_pool_t *p;
// 开辟内存
p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
if (p == NULL) {
// 开辟失败直接返回
return NULL;
}
// last指向可用内存的起始地址
p->d.last = (u_char *) p + sizeof(ngx_pool_t);
p->d.end = (u_char *) p + size; // 指向内存末尾地址
p->d.next = NULL;
p->d.failed = 0;
size = size - sizeof(ngx_pool_t); // 真实可用内存大小
// 开辟内存小于一个页面,max = size 大于一个页面 max = 4095字节
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
p->current = p; // 指向第一个可用内存池
p->chain = NULL;
p->large = NULL;
p->cleanup = NULL;
p->log = log;
return p;
}
当第一次创建内存池时,此时就只有一个内存池,nginx在开辟内存时,会将内存池头部信息放入内存池中。
nginx内存开辟 ---- ngx_memalign函数
ngx_memalign函数有不同版本的,内存对齐也有内存不对齐的,这三个函数都是unix上的接口。
// 考虑内存对齐的两个函数,由两个宏函数进行控制
#if (NGX_HAVE_POSIX_MEMALIGN) // 如果定义这个宏,调用ngx_memalign函数就调用是这个函数
void * ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
{
void *p;
int err;
err = posix_memalign(&p, alignment, size); // 系统调用函数分配内存
if (err) {
ngx_log_error(NGX_LOG_EMERG, log, err,
"posix_memalign(%uz, %uz) failed", alignment, size);
p = NULL;
}
ngx_log_debug3(NGX_LOG_DEBUG_ALLOC, log, 0,
"posix_memalign: %p:%uz @%uz", p, size, alignment);