分配函数ngx_palloc_large
static void *
ngx_palloc_large(ngx_pool_t *pool, size_t size)
{
void *p;
ngx_uint_t n;
ngx_pool_large_t *large;
p = ngx_alloc(size, pool->log); // malloc
if (p == NULL) {
return NULL;
}
n = 0;
// 复用已释放空间内存头信息 M1
for (large = pool->large; large; large = large->next) {
if (large->alloc == NULL) {
large->alloc = p;
return p;
}
if (n++ > 3) {
break;
}
}
// 大块内存的头信息也是存在小块内存池中!!
large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
if (large == NULL) {
ngx_free(p);
return NULL;
}
// 头插
large->alloc = p;
large->next = pool->large;
pool->large = large;
return p;
}
整体内存池图示:
注意:其中大块内存的块头信息也是存放在小块内存池中:
large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
图示如下:
大块内存释放函数ngx_pfree
ngx_int_t
ngx_pfree(ngx_pool_t *pool, void *p)
{
ngx_pool_large_t *l;
for (l = pool->large; l; l = l->next) {
if (p == l->alloc) {
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
"free: %p", l->alloc);
ngx_free(l->alloc); // free
l->alloc = NULL; //
return NGX_OK;
}
}
return NGX_DECLINED;
}
注意到块头的空间并没有释放只是将alloc域置空,到后面再创建大块内存时可以复用,可查看分配函数中M1代码处