【nginx流程分析之内存分配】

写在前面

这个文章主要是为了分析nginx中是如何进行内存分配,是对上一篇文章nginx流程分析的继承,详见nginx流程分析.
所以这篇文章主要就是为了写ngx_create_pool,详见下图
在这里插入图片描述

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

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

ngx_pool_t

首先看一下ngx_pool_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 {
    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;
};
struct ngx_pool_large_s {
    ngx_pool_large_t     *next;
    void                 *alloc;
};
struct ngx_pool_cleanup_s {
    ngx_pool_cleanup_pt   handler;
    void                 *data;
    ngx_pool_cleanup_t   *next;
};

ngx_pool_data_t

last和end分别是下一个ngx_pool_t结构体开始的指针,然后end自然就是最后一个ngx_pool_t的指针。next指向下一个ngx_pool_t结构体的指针。failed 就是申请失败的次数。

max

就是当前最多可用的内存

current

就是当前的ngx_pool_t的指针,

ngx_chain_t

暂时没看到有什么作用,类型定义如下:

struct ngx_chain_s {
    ngx_buf_t    *buf;
    ngx_chain_t  *next;
};

large

就是申请的大内存,是一个void的指针,同时next指向下一个内存地址

typedef struct ngx_pool_large_s  ngx_pool_large_t;
struct ngx_pool_large_s {
    ngx_pool_large_t     *next;
    void                 *alloc;
};

cleanup

从名字可以看出来是清理内存的方法,然后看一下定义

struct ngx_pool_cleanup_s {
    ngx_pool_cleanup_pt   handler;
    void                 *data;
    ngx_pool_cleanup_t   *next;
};

确实也是这样,handler是清理的具体实现

typedef void (*ngx_pool_cleanup_pt)(void *data);

log

log 就是用来进行日志,这个在前面已经初始化。

进行初始化

申请了一个 类型为ngx_pool_t,名称为p的变量。
然后就是申请内存,然后用的是ngx_memalign,根据NGX_POOL_ALIGNMENT也就是16位进行内存对齐的内存。因为在调用的时候传的是1024,也就是此时的size是1024,所以我们这边申请的是以 16byte对齐内存,大小为1026个字节的大小的一块内存。
然后出去ngx_pool_t占用的80字节的内存,还是944字节。
然后 p->d.last 指向开头,p->d.last 指向结尾。size就是剩余可以用的字节大小,p->max 其实和size一样,最多可用的字节大小,如果申请超过这么大的内存,那么就要申请大块内存。
文件描述可能有点枯燥,这边借用网上的一张图,可能会更加形象。
在这里插入图片描述
注意,这边这个大佬用的是32的电脑,所以sizeof(ngx_pool_t)是40,可用内存是 1024-40= 984,而我们的电脑是64位的,所以sizeof(ngx_pool_t)是80,可用内存是1024-80=944;

之所以是80,是因为ngx_pool_t有十个成员,然后有人疑惑max为什么也是8个字节,这个是因为c语言出于cpu利用率等原因的考虑,底层已经做了内存对齐,不足8个字节会自动补齐,因此也是8个字节。至于为什么是8个字节,是因为我们的电脑是64位,也就是8个字节。

ngx_create_pool 结束

将p返回,初始化结束。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值