您的位置:首页 > 运维架构 > Nginx

Nginx源码剖析—内存池结构ngx_pool_t

2017-03-13 14:40 666 查看
一.相关结构:.

ngx_pool_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;//释放内存池的callback;

    ngx_log_t            *log;//日志信息

};

 

Ngx_pool_data_t结构:该结构就是包含了操作该内存池的数据的一些指针

typedef   struct  {

u_char      *last; //当前的数据区的已经使用的数据的结尾

u_char      *end;  //表示该内存池结束的位置(end-last就是当前内存池中未使用的部分)

ngx_pool_t   *next; //指向下一块内存块,内存池中有多个内存块,内存块通过该指针连接

ngx_uint_t   failed; //内存池分配内存失败次数

}ngx_pool_data_t;

ngx_pool_large_t结构:表示大块内存

struct  ngx_pool_large_s{

        ngx_pool_large_t  *next;//指向下一块大块内存

        void *alloc;//指向分配的大块内存

};

ngx_pool_cleanup_t结构:这个结构用来表示内存池中的数据的清理handler。

Struct ngx_pool_cleanup_s{

  ngx_pool_cleanup_pt  handler;//表示清理函数

  void*data;                                    //表示传递给清理函数的数据

  ngx_pool_cleanup_t*next;     //表示下一个清理handler

};



当destroy这个pool的时候会遍历清理handler链表,然后调用handler;

二.内存池的相关操作:



创建内存池---------ngx_create_pool();

销毁内存池 -------ngx_destroy_pool()和ngx_pfree()//ngx_pfree函数只释放large链表中申请的内存,普通内存有destroy函数统一释放

重置内存池------ngx_reset_pool()

分配内存-------1.void *ngx_palloc(ngx_pool_t *pool,size_t  size);//创建一个数据区为size的内存池

                                  2.void *ngx_pnalloc(ngx_pool_t*pool,size_t size);//不进行内存对齐

                                  3.void *ngx_pcalloc(ngx_pool_t*pool,size_t  size);//将分配的内存空间初始化

                                  4.void *ngx_pmemalign(ngx_pool_t *pool,size_t size,size_t alignment);//返回一个基于alignment大小size的内存空间,地址为alignment整数倍,
     alignment为2的幂

     内存分配返回值为分配的内存起始地址,函数中封装了最基本的内存分配函数,

如free/malloc/memalign/posix_memalign分别被封装为ngx_free;ngx_alloc/ngx_calloc;ngx_menalign;

1.创建内存池:



注:在NGX_MAX_ALLOC_FROM_POOL(ngx_pagesize-1)中,ngx_pagesize = getpagesize(),getpagesize()函数功能是取得内存分页的大小;

2.内存分配

  Nginx中对内存的管理分为大块内存和小块内存,当某一个申请内存大于MAX就从大内存分配空间,否则从小块内存中分配,nginx内存池在创建时就设定好了大小,

在以后分配小块内存时,如果内存不够,重新创建一块小内存链接到内存池,当要分配大块内存,则是在内存池外再分配空间进行管理。



(2)ngx_palloc_block的实现,这个函数功能是重新分配一块内存池,然后链接到当前内存池的数据区指针,new的这个内存池大小和它的父内存池一样大

       _


注:该函数分配一块内存之后,last指针指向ngx_pool_data结构之后数据区的起始位置,而创建内存池时,last指针指向ngx_pool_t结构体之后。

为什么要这样设置current,主要原因是在ngx_palloc中分配内存是从current开始,而这里就是设置current为比较新分配的内存,当failed大于4说明我们至少请求了4次内存分配,都不能满足我们的请求,此时我们就假设老的内存已经没有空间,从新的内存开始。

(3)ngx_palloc_large,这个函数也是很简单的malloc一块ngx_pool_large_t然后链接到主的内存池上。直接在系统堆中分配一块size

空间,查找一个large区,将分配的空间交给它;将large链接到内存池。



(4)内存池重置ngx_reset_pool():作用释放大块内存,重置所有的小块内存



不理解:为什么在重置小块内存时,last要指向ngx_pool_t后边而不是ngx_pool_data_t;

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: