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;
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;
相关文章推荐
- nginx源码分析—内存池结构ngx_pool_t及内存管理
- 【nginx源码学习与运用 一】内存池结构ngx_pool_t
- 菜鸟nginx源码剖析数据结构篇(九) 内存池ngx_pool_t
- nginx源码分析—内存池结构ngx_pool_t及内存管理
- Nginx源码分析---内存池结构ngx_pool_t及内存管理
- 菜鸟nginx源码剖析数据结构篇(九) 内存池ngx_pool_t
- nginx源码分析—内存池结构ngx_pool_t及内存管理
- 菜鸟nginx源码剖析数据结构篇(九) 内存池ngx_pool_t
- nginx源码学习(二) 内存池结构 ngx_pool_t
- nginx源码分析—内存池结构ngx_pool_t及内存管理(精辟)
- nginx源码分析—内存池结构ngx_pool_t及内存管理
- nginx源码分析—内存池结构ngx_pool_t及内存管理
- nginx源码分析—内存池结构ngx_pool_t及内存管理
- nginx源码分析—内存池结构ngx_pool_t及内存管理
- 菜鸟nginx源码剖析数据结构篇(九) 内存池ngx_pool_t
- Nginx内存池结构ngx_pool_t及内存管理
- Nginx源码分析(3)之——内存池(ngx_pool_t)分析
- nginx源码解析(二)-内存池与内存管理ngx_pool_t
- nginx源码剖析---队列结构ngx_queue_t
- Nginx源码剖析--ngx_cycle_s结构体分析