当前位置 主页 > 服务器问题 > nginx问题汇总 >

    详解Nginx中基本的内存池初始化配置

    栏目:nginx问题汇总 时间:2018-11-30 16:27

    Nginx由其自己实现的内存池结构对内存进行管理,这里我们就来详解Nginx的基本内存池初始化配置,需要的朋友可以参考下

    ngx_cycle 的初始化
    整个初始化过程中,最重要的就是全局变量 nginx_cycle 的初始化,很多变量都是在这个过程中初始化的

    nginx_cycle 又是通过两个局部变量 init_cycle 和 cycle 实现初始化的

    事实上,日志初始化也可以算是对 nginx_cyle 的初始化,因为在代码中接下来马上要发生的就是一个赋值

    ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));init_cycle.log = log;ngx_cycle = &init_cycle;// 创建内存池 1KBinit_cycle.pool = ngx_create_pool(1024, log);if (init_cycle.pool == NULL) { return 1;}// 保存调用参数到全局变量,init_cycle 只用于提供 log 参数if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) { return 1;}// 保存配置文件路径、程序运行路径、调用参数到 init_cycleif (ngx_process_options(&init_cycle) != NGX_OK) { return 1;}// 获取操作系统信息、CPU信息、最大连接数、是否支持非阻塞连接等if (ngx_os_init(log) != NGX_OK) { return 1;}/* * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init() */// 对齐校验表if (ngx_crc32_table_init() != NGX_OK) { return 1;}// 获取所有继承连接fd的相关信息if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) { return 1;}

     

    内存池
    nginx 是通过资源集中管理的方式管理资源的,即打开所有即将要用的资源,以备随时取用,无论是文件还是内存

    这样做的好处是避免了每次创建、打开资源造成的性能消耗

    因此,便有了内存池模块,用来集中申请内存资源并进行内存资源的管理和分配

    内存池结构:

    // struct ngx_pool_data_t// 内存池数据块结构 {{{typedef struct { u_char    *last;  // 当前内存分配的结束位置 u_char    *end;  // 内存池的结束位置 ngx_pool_t   *next;  // 下一内存池 ngx_uint_t   failed; // 内存分配失败计数} ngx_pool_data_t; // }}}// struct ngx_pool_s// 内存池结构 {{{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; // 析构函数 ngx_log_t   *log;  // 内存分配相关的log}; // }}}

    在这个函数中,使用了一个封装好的函数 ngx_memalign,这个函数是对系统中按照数据对齐方式分配内存的函数的封装,在不同的系统中实现方式不同,通过宏定义,实现了操作系统的适配,这是一个很漂亮的技巧

    #if (NGX_HAVE_POSIX_MEMALIGN)// void * ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)// 用数据对齐的方式进行内存分配 {{{void *ngx_memalign(size_t alignment, size_t size, ngx_log_t *log){ void *p; int err; // size 单位是 byte 而不是 bit 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); return p;} // }}}#elif (NGX_HAVE_MEMALIGN)// void * ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)// 用数据对齐的方式进行内存分配 {{{void *ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)