目录
实现思路——分而治之
Nginx 的内存池结构图
结构体设计
内存池设计:
数据区属性设计:
大块内存区设计:
伪代码解释:
数据结构实现
实现思路——分而治之
算法结构:链表+顺序表
1、对于每个请求或者连接都会建立相应的内存池,一次申请较大的内存区当作取放的池子。
2、可以直接从内存池中申请所需要的内存,减少了系统调用的次数和时间。
3、不用特意去管内存的释放,当内存池使用完成之后一次性销毁内存池即可。
4、区分大小内存块的申请和释放:
大于池尺寸的定义为大内存块,使用单独的大内存块链表保存,即时分配和释放。
小于等于池尺寸的定义为小内存块,直接从预先分配的内存块池中提取。
5、如若不够 就扩充池中的内存,在生命周期内对小块内存不做释放,直到最后统一销毁。
Nginx 的内存池结构图
结构体设计
内存池设计:
1、数据区
2、大内存区
2、记录最大存储量(固定):判断用大块还是小块内存
3、指向当前使用的内存区地址
数据区属性设计:
1、内存块可用部分的起始地址
2、这个内存块的结束位置
3、指向下一个内存块的指针
4、申请失败次数
大块内存区设计:
1、大块内存的起始地址
2、指向下一个大块内存的指针
伪代码解释:
//第一块:包含大小块、指引信息 struct ngx_pool_t{ //数据区------------------------------------------- lagre_next;//大块头节点 data_next;//小块头节点 current;//当前正在使用的小块内存区 max_size;//存储区最大容量限度:(固定)==end-begin }; //链表:其他小块和大块 //采用尾插法 struct ngx_pool_data_t{ begin;//不断更新可存区域的起始位置 end;//末尾位置 next;//下一块内存区 failed_count;//申请失败次数:该内存块不满足 }; //采用头插法 struct ngx_pool_large_t{ next; data; };
数据结构实现
typedef struct ngx_pool_s ngx_pool_t; typedef struct ngx_pool_large_s ngx_pool_large_t; struct ngx_pool_large_s{ ngx_pool_large_t *next; // 指向下一块大内存块的指针 void *alloc; // 大内存块的起始地址 }; typedef struct { u_char *last; // 保存当前数据块中内存分配指针的当前位置。每次Nginx程序从内存池中申请内存时, // 从该指针保存的位置开始划分出请求的内存大小,并更新该指针到新的位置。 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; // 当前数据块最大可分配的内存大小(Bytes) ngx_pool_t *current; // 当前正在使用的数据块的指针 ngx_pool_large_t *large; // pool 中指向大数据块的指针(大数据块是指 size > max 的数据块) };