高性能内存池设计【内存池框架】

🚀内存池实现思路

  • 对于每个请求或者连接都会建立相应的内存池,建立好内存池之后,我们可以直接从内存池中申请所需要的内存,不用去管内存的释放,当内存池使用完成之后一次性销毁内存池。

  • 区分大小内存块的申请和释放,大于池尺寸的定义为大内存块,使用单独的大内存块链表保存,即时分配和释放;小于等于池尺寸的定义为小内存块,直接从预先分配的内存块中提取,不够就扩充池中的内存,在生命周期内对小块内存不做释放,直到最后统一销毁。


🍎Nginx 内存池结构图

在这里插入图片描述
现在就来掰扯掰扯这个结构吧!!
在这里插入图片描述
别急,具体的数据结构解析在下面呢!!


⭐第一个内存块的结构

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 的数据块)
};
  • max变量用来表示内存块最大可分配的内存大小(内存池设置的块大小-第一块结构体的大小,也有可能是NGX_MAX_ALLOC_FROM_POOL设置的大小),如果一个内存需要分配的大小大于max,那么它就属于大内存块得使用ngx_pool_large_t*进行链接,而不能当小内存块进行处理分配
    以下是nginx线程池对于max赋值的语句
    在这里插入图片描述

  • current变量指向下一个当有小内存块需要malloc时所开始遍历的数据块(因为内存池是由多块内存块组成,当有小内存需要分配时,我们需要从其中一个内存块中开始寻找哪个内存块可以提供这次分配),这个值和ngx_pool_data_t中的failed变量相关联

⭐ngx_pool_t 详细解析

typedef struct {
    u_char               *last;         // 保存当前数据块中内存分配指针的当前位置
    u_char               *end;          // 保存内存块的结束位置
    ngx_pool_t           *next;         // 内存池由多块内存块组成,指向下一个数据块的位置
    ngx_uint_t            failed;       // 当前数据块内存不足引起分配失败的次数
} ngx_pool_data_t;

ngx_pool_t 结构示意图 (大小为1024的池)
在这里插入图片描述

  • 使用last和end来判断当前内存块是否够这次小内存的分配,同样用于分配时的定位。
  • failed变量用来存储当有小内存需要分配时,而当前这个块的空间无法为此次分配提供空间的次数,可以设置规则,比如当当前的块失败次数≥5,那么就将本来指向当前块的current指针(第一个内存块中的current指针,往上文翻翻就知道是什么啦)指向别的块,是一个用来评价当前内存池是否空间富裕的指。
  • next变量用来指向下一个内存块的位置。

🎂Nginx 内存池基本操作

内存池创建、销毁和重置:

在这里插入图片描述

内存池申请、释放和回收操作:

在这里插入图片描述
内存池申请、释放和回收操作:
在这里插入图片描述

内存池部分还没结束,接下来更新Nginx内存池的源码分析将会对内存池的操作进行更加详细的分析和解释,非常感谢您能够看到这,希望对您有所帮助,当然,如果对本文中的一些观点持不同意见或者看法的请一定一定要在评论区中进行说明,非常感谢😀
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值