C++实现简易内存池(详细版)

内存池的原理

内存池是一种 预先分配和管理内存 的技术,主要用于 提高内存分配效率,减少内存碎片,并优化程序性能。

预先分配一大块内存(称为“池”),避免频繁调用 malloc/new 和 free/delete。

自主管理内存分配和释放,减少系统调用的开销。

减少内存碎片,提高内存利用率。

本贴主要介绍可变长内存池的设计及实现

小内存分配

当用户申请的内存是小内存时(这里的小内存指的是小于small_buffer_capacity),检查small_block组成的链表,图示的是一开始初始化memory_pool的样子,如果余下内存空间足够放得下用户申请的内存(可以理解为图中绿色部分的内存量大于申请内存量)那么就将small_block的可用指针移动。(这里不理解数据结构中各个变量的作用,先不着急,接下来会详细阐述,这一部分请尽量体会内存池的运行逻辑,加油)。

大内存分配

当用户的内存过大(大于small_buffer_capacity时)就需要使用big_block来管理这些内存块,在内存池看来,各个数据结构是需要占据小内存的,需要当作申请小内存来处理,而申请的大内存就直接开辟一个大内存即可,形成一个大内存链来管理。

扩容

其实聪明的你应该会有疑问,当我申请小内存时,我原先预先开辟的内存块不够用了怎么办?那么,我们就需要动态扩容,同样再开辟一个内存块,将新的small_block来管理这个内存块即可。

好啦,你已经了解了内存池的运行模式啦,那就动手设计吧

内存池各个数据结构设计

由于nignix中内存池是纯C语言书写的,这里我们用C++进行改写,那么我们就需要预料到,内存池类是不是在运行过程中只保留一份,不必存在多个对象,那么其内部的成员函数怎么办?该如何设计呢?是不是很熟悉,对!就是单例模式!我们只需要把成员函数static一下,那么它们就独立于内存池类了,并且只会保留一份,不必占用过多内存,什么?不知道设计模式,害,等我更新。

内存池类结构
class memory_pool {
public:
    size_t small_buffer_capacity;//小块大小,作为初始数据
    small_block* cur_usable_small_block;//当前可用小块
    big_block* big_block_start;//大块头
    small_block small_block_start[0];//小块头
    static memory_pool* createPool(size_t capacity);//创建内存池
    static void destroyPool(memory_pool* pool);//销毁内存池
    static char* createNewSmallBlock(memory_pool* pool, size_t size);//创建小块
    static char* mallocBigBlock(memory_pool* pool, size_t size);//创建大块
    static void* poolMalloc(memory_pool* pool, size_t size);//申请块api
    static void freeBigBlock(memory_pool* pool, char* buffer_ptr);//free函数
};
管理小内存的结构
class small_block {
public:
    char* cur_usable_buffer;//当前可以使用的小块地址
    char* buffer_end;//地址范围的末尾
    small_block* next_block;//下一个可以使用的块
    int no_enough_times;//寻找失
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值