一个简单的内存池

为什仫要使用内存池?

     1.通常我们用new/delete和malloc/free来管理内存,可能会需要频繁的调用内存,减少运行时间,增加效率.

     2.避免内存碎片

传统的new/delete的弊端>

     1.分配内存时要查看空闲分区表,根据一定的算法来分配,比如最佳适应算法,最差适应算法...,然后更新空闲分区表.释放的时候,也需要在空闲分区表中加入该释放的内存,如果上下也是空闲的还需要将内存碎片合并为一个大的空闲分区 .

     2.默认的内存管理函数还考虑了多线程的应用,增加了开销.

     3.频繁的申请和释放还将导致内存碎片.


    内存池是在真正使用内存之前,先申请一个大的内存块.当需要使用内存时,就从内存池中分配一块使用,当使用完了不用还给操作系统而是还给内存池。如果内存池不够就向内存申请一块更大的内存块.

 存在内存池的好处?

     1.因为申请的内存都比较大,所以降低了外部碎片(内存碎片).

     2.因为是一次性申请一块较大的内存,避免了频繁的向内存的请求操作,提高了内存的分配效率,避免内存泄漏.

 内碎片

        分配内存时的大小比需求的内存大,有部分内存未使用,这块未使用的内存就称为内碎片

 外碎片/内存碎片

   当空闲的存储器的和计起来足够满足一个分配请求,但是没有一个单独的空闲块足够大可以处理这个请求

 

  

 下面介绍一种高效的内存池,它的实现类似链表,链表上的每个结点都是一个对象池,如果申请对象则去内存池中申请,归还的时候还给内存池即可.

   

   

#pragma once

#include<vector>
#include<string>

template<class T>
class ObjectPool
{
	struct BlockNode
	{
		void *_memory;     //内存块
		BlockNode *_next;
		size_t _objNum;    //内存对象的个数
		BlockNode(size_t objNum)
			:_objNum(objNum)
			,_next(NULL)
		{
			_memory=malloc(_itemSize*objNum);
		}
		~BlockNode()
		{
			free(_memory);
		}
	};
protected:
	size_t _countIn;        //当前结点的计数
	BlockNode *_first;
	BlockNode *_last;
	size_t _maxNum;         //结点申请内存块对象的个数
	static size_t _itemSize;    //单个对象的大小
	T *_lastDelete;
public:
	ObjectPool(size_t initNum=32,size_t maxNum=1000000)
		:_countIn(0)
		,_maxNum(maxNum)
		,_lastDelete(NULL)
	{
		_first=_last=new BlockNode(initNum);
	}
	~ObjectPool()
	{
		Destroy();
	}
	void Destroy()
	{
		BlockNode *cur=_first;
		while (cur)
		{
			BlockNode *del=cur;
			cur=cur->_next;
			delete del;
		}
		_first=_last=NULL;
	}
	T* New()
	{
		if(_lastDelete)
		{
			//优先考虑以前释放的空间
			T *obj=_lastDelete;
			_lastDelete=*((T **)_lastDelete);
			return new(obj)T;
		}
		if(_countIn >= _last->_objNum)   //申请新的结点和对象
		{
			size_t size=2*_countIn;
			if(size > _maxNum)
				size=_maxNum;
			_last->_next=new BlockNode(size);
			_last=_last->_next;
			_countIn=0;
		}
		T *obj=(T *)((char *)_last->_memory + _countIn*_itemSize);
		_countIn++;
		return new(obj)T();
	}
	void Delete(T *ptr)
	{
		if(ptr)
		{
			ptr->~T();
			*((T **)ptr)=_lastDelete;
			_lastDelete=ptr;
		}
	}
protected:
	static size_t GetItemSize()
	{
		if(sizeof(T) > sizeof(T *))
			return sizeof(T);
		else
			return sizeof(T *);
	}
};
template<class T>
size_t ObjectPool<T>::_itemSize=ObjectPool<T>::GetItemSize();

  

  over~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值