Nginx内存池源码刨析

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);

    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值