nginx使用内存池对内存进行管理,内存分配可以归结为大内存分配小内存分配。若申请的内存大小比同页的内存池最大值max还大,则是大内存分配,否则为小内存分配。

    1. 大内存的分配请求不会直接在内存池上分配,而是直接向系统申请一块内存(就像直接使用malloc分配内存一样),然后将这块内存挂到内存池头部的large字段下
    2. 小内存分配,则是从已有的内存池数据区中分配出一部分内存。
    1. // 内存池结构体 core/nginx_palloc.h
    2. // 内存池数据模块
    3. typedef struct {
    4. u_char *last; // 当前内存分配的结束位置,即下一段可分配内存的起始位置
    5. u_char *end; // 内存吃的结束位置
    6. ngx_pool_t *next; // 指向下一个内存池
    7. ngx_uint_t failed; // 记录内存池内存分配失败的次数
    8. } ngx_pool_data_t; // 维护内存池的数据块
    9. // 内存池管理模块,内存池头部结构
    10. struct ngx_pool_s {
    11. ngx_pool_data_t d; // 内存池数据模块
    12. size_t max; // 内存池数据块的最大值
    13. ngx_pool_t *current; // 指向当前内存池
    14. ngx_chain_t *chain; // 指向一个ngx_chain_t结构
    15. ngx_pool_large_t *large; // 大块内存链表,即分配空间超过max的内存
    16. ngx_pool_cleanup_t *cleanup; // 析构函数,释放内存池
    17. ngx_log_t *log; // 内存池日志
    18. };

    大块内存分配如下:

    1. typedef struct ngx_pool_large_s ngx_pool_large_t;
    2. struct ngx_pool_large_s {
    3. ngx_pool_large_t *next; // 指向下块要分配的内存
    4. void *alloc; // 指向分配的大块内存
    5. };