【C++】2.高并发内存池 -- 如何设计一个定长内存池

博客主题:如何设计一个定长内存池
个人主页:https://blog.csdn.net/sobercq
CSDN专栏:https://blog.csdn.net/sobercq/category_12884309.html
Gitee链接:https://gitee.com/yunshan-ruo/high-concurrency-memory-pool



前言

上期我们说到malloc,我们知道malloc,在C/C++中动态申请内存都是通过malloc去申请内存, 并且malloc就是一个内存池。但是malloc因为要兼容通用,它什么场景下都可以用,但是什么场景下都可以用就意味着什么场景下都不会有很高的性能,所以我们要设计一个针对点一定场景下的内存池,来实现高性能。
在这里插入图片描述
所以本期我们就先设计一个定长内存池,先熟悉一下简单内存池是如何控制的,第二他会作为我们后面高并发内存池的一个基础组件。

那定长内存池就是针对固定大小内存块的申请和释放的内存池,由于定长内存池只需要支持固定大小内存块的申请和释放,因此我们可以将其性能做到极致,并且在实现定长内存池时不需要考虑内存碎片等问题,因为我们申请/释放的都是固定大小的内存块。

定长内存池

1.如何实现定长?

我们先创建和Test.cpp,ObjectPool.h,那如何实现定长,其一我们可以采用非类型模板参数来实现定长。

template<size_t N>

class ObjectPool
{
   
   
};

其二呢,我们也可以通过类型模板参数,采用这种方法设计我们也把它叫做对象池,即ObjectPool,在创建对象池时,对象池可以根据传入的对象类型的大小来实现“定长”,比如,创建定长内存池时传入的对象类型是内置类型,那么该内存池就只支持内置类型字节大小的内存块的申请和释放,如果是自定义类型,那我们的内存块大小就是sizeof(T)。

template<class T>

class ObjectPool
{
   
   
};

2.分配内存

首先,我们的内存池需要去堆上申请一块内存,这块内存假设我们已经申请下来了,我们要管理这块内存。那如何分配这大块内存呢?
如图所示,我们每次只需要在头部位置加对应大小的字节就可以了。
在这里插入图片描述
所以为了方便管理我们申请下来的大块内存,就需要用一个指针来管理。

//void* _memory
char* _memory

但是void这个类型没有意义,又不能加也不能减,还要强转,所以我们取最小的char,方便我们去切内存块,char指针+1也是+1字节。容易切分内存。

3.回收内存

那我们使用完这些划分后的内存块后,应该如何管理呢?我们可以用一个自由链表来管理内存,将回收来的内存块想象成一个链表的结点。
在这里插入图片描述
通过上图,我们能明确知道,这个对象池的构造了。

template <class T>

class ObjectPool
{
   
   
private:
	char* _memory = nullptr;	//管理系统申请的大块内存
	void* _freelist = nullptr; //管理回收内存
};

3.如何New对象

我们既然已经知道我们的内存池的构造了,接下来就是如何去new一个对象。
刚才我们也说过,对象池,其大小是一个T的大小,所以我们可以先通过malloc去申请一块大点的空间,然后将其分配给对象。
在这里插入图片描述

T* New()
{
   
   
	T* Obj = nullptr;
	if (_memory == nullptr)
	{
   
   
		_memory = (char*)malloc(128 * 1024);//128K内存块
		if (_memory == nullptr)
		{
   
   
			throw std::bad_alloc();//申请失败,抛异常
		}
	}

	Obj = (T*)_memory;
	_memory += sizeof(T);
	return Obj;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值