1.创建内存池:
ngx_pool_t * ngx_create_pool(size_t size , ngx_log_t log);
在linux下,开辟内存有三个函数:
(1).不进行内存对齐的函数:malloc()
(2).进行内存对齐的俩个函数:memalign( ) 和 posix_memalign( )
如果定义了NGX_HAVE_POSIX_MEMALIGN,程序将调用posix_memalign( );
如果定义了NGX_HAVE_MEMALIGN,程序将调用memalign ( );
如果以上俩个都没有定义,则直接调用malloc();
内存对齐默认以16B对齐,宏定义为:#define NGX_POOL_ALLGNMENT 16
通过这几个开辟内存的系统调用就得到了我们的ngx_pool_t类型的内存区域。
接下来对该块内存的节点进行初始化赋值:小块内存的节点部分
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;
然后对MAX进行指定:在内存池能申请的最大内存字节数
p->max=(size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
意思是说:如果size<4KB,那么max的值就取size的值,否则最大取4095B;
#define NGX_MAX_ALLOC_FROM_POOL 4KB-1; 在X86 32位的系统一个页面位4KB
因此也就是说,给内存空间最大可分配内存不能超过4KB
最后对大块内存头节点进行初始化:
p->current = p;
p->large = NULL;
p->cleanup = NULL;
p->log = p;
return p;
最后返回指向分配号的内存空间的指针。
假设:ngx_create_pool(1024,log); 内存布局大概是这样的:
假设内存的其实地址是10,实际可分配的内存为984B, 1024 - 40;
2.销毁内存池:主要分三步
ngx_destroy_pool(ngx_pool_t * pool);
1.对于链表上的数据区,调用cleanup指向handle回调函数进行数据清理
//遍历释放cleanup链表上的可回收的内存
2.对large指向的大块内存链表上的区域,直接调用free归还
#define ngx_free free ;
//遍历释放大块内存链表上的每个节点
3.最后释放内存池本身管理需要或者占用的内存区域
//即释放小块内存 数据部分
3.重置内存池: 将内存池恢复到初始分配状态
ngx_reset_pool (ngx_pool_t * pool)
1.既然要回复到原始状态,先要释放调申请的所有大块内存:
2.将所有小块内存last指针指向刚分配的位置
需要注意的是:小块内存的内存并没有被释放,而是等下一次申请,使用时直接将原来的数据覆盖掉。