自定义通用型空间配置器

使用通用型空间配置器,支持提供stl容器的空间分配功能。


设计上:

(1)自定义空间配置器使用内存池管理器来分配内存。

(2)内存池管理器包含1024*1024 + 1024 个内存池的数组(附带1024*1024 + 1024 个锁,单逻辑线程的可以不使用)。对应不同的内存分配需求大小就寻找对应的内存池来分配(大小限制在1024*1024 字节以内),每个内存池使用链表数据结构。

1、自定义空间配置器

(1)自定义空间配置器

下面是自定义空间配置器定义代码:

template <class _Ty>
class zMemoryAllocator
{
public:
	typedef size_tsize_type;
	typedef _Ty  *pointer;
	typedef _Ty & reference;
	typedef const _Ty  *const_pointer;
	typedef const _Ty & const_reference;
	typedef _Ty value_type;
	typedef int difference_type;

	zMemoryAllocator()
	{ // construct default allocator (do nothing)
	}


	template<class _Other>//=号操作符重载
	zMemoryAllocator<_Ty>& operator = (const zMemoryAllocator<_Other>& alr)
	{ // assign from a related allocator (do nothing)
	return (*this);
	}

	template<class _Other>
	zMemoryAllocator(const zMemoryAllocator<_Other>& alr)
	{ // construct by copying (do nothing)
	}


	template<class _Other>
	struct rebind
	{ // convert an allocator<_Ty> to an allocator <_Other>
	typedef zMemoryAllocator<_Other> other;
	};


	pointer allocate(size_type _Count)//分配内存函数重载
	{
		if(_Count == 0) _Count = 1;
		return (pointer)zMemoryAlloc::allocator(sizeof(_Ty) * _Count);
	}

	
	pointer allocate(size_type _Count,const void *)
	{
		if(_Count == 0) _Count = 1;
		return (pointer)zMemoryAlloc::allocator(sizeof(_Ty) * _Count);
	}
	
	pointer address(reference _Val) const
	{ // return address of mutable _Val
		return (&_Val);
	}

	const_pointer address(const_reference _Val) const
	{ // return address of nonmutable _Val
		return (&_Val);
	}

	void construct(pointer _Ptr, const _Ty& _Val)
	{
		std::_Construct(_Ptr,_Val);
	}
	
 	// deallocate object at _Ptr, ignore size
	void deallocate(pointer _Ptr, size_type size)
	{
		zMemoryAlloc::free(_Ptr);
	}
	
	// destroy object at _Ptr
	void destroy(pointer _Ptr)
	{ 
		std::_Destroy(_Ptr);
		//_Ptr->~_Ty();
	}
	
	// estimate maximum array size
	size_t max_size() const
	{ 
		size_t _Count = (size_t)(-1) / sizeof (_Ty);
		return (0 < _Count ? _Count : 1);
	}
};

// assign from a related allocator (do nothing)
template<class _Ty,class _Other>
inline bool operator == (const zMemoryAllocator<_Ty>& alr1,const zMemoryAllocator<_Other>& alr2)
{ 
	return true;
}

// assign from a related allocator (do nothing)
template<class _Ty,class _Other>
inline bool operator != (const zMemoryAllocator<_Ty>& alr1,const zMemoryAllocator<_Other>& alr2)
{ 
	return false;
}

(2)自定义内存分配器使用的内存管理基类

内存池管理器设计

1024*1024 + 1024 个内存池的数组(附带1024*1024 + 1024 个锁,单逻辑线程的可以不使用锁)。

对应不同的内存分配需求大小就寻找对应的内存池来分配(大小限制在1024*1024 字节以内),每个内存池是个链表。

/**
* \brief 内存池管理基类
 */
class zMemoryAlloc
{
protected:
	/**
	* \brief 构造函数
	*
	*/
	zMemoryAlloc()
	{
	};
	/**
	* \brief 析构函数
	*
	*/
	~zMemoryAlloc()
	{
	};
public:
	/**
	* \brief 内存池锁(数组)
	*/
	static zMutex alloc_lock[1024 * 1024 + 1024];
	/**
	* \brief 内存池(多一个指针)
	*
	*/
	static MemPool2 alloc[1024 * 1024 + 1024];
public:
	//重载操作符new
	static void* operator new( size_t Size , void *);
	static void* operator new( size_t Size , void *,const char* filename,int line );
	static void* operator new( size_t Size);
	static void* operator new( size_t Size,const char* filename,int line );
	static void operator delete( void* Ptr );
	static void operator delete( void* Ptr ,const char* , int);
	static void* operator new[]( size_t Size , void *);
	static void* operator new[]( size_t Size  , void *,const char* filename,int line);
	static void* operator new[]( size_t Size );
	static void* operator new[]( size_t Size ,const char* filename,int line);
	static void operator delete[]( void* Ptr );
	static void operator delete[]( void* Ptr ,const char* , int);
public:
	static void *allocator(size_t Size);
	static void free(void* Ptr);
};

zMutex zMemoryAlloc::alloc_lock[1024 * 1024 + 1024];//锁数组
MemPool2 zMemoryAlloc::alloc[1024 * 1024 + 1024];//内存池管理器数组
void* zMemoryAlloc::operator new( size_t Size  , void *ptr)
{
	return ptr;
}
void* zMemoryAlloc::operator new( size_t Size )
{
	assert(Size != 0);
	Size += sizeof(_Node);
	if(Size <= 1024)
	{
	Size = (Size + 0XF) & (0XFFFFFFFF - 0XF);
	}
	else  
	{
	Size = (Size + 0X1F) & (0XFFFFFFFF - 0X1F);
	}
	   
	if(Size < 1024 * 1024)//在1024*1024字节范围内分配内存,才使用小内存分配器(超过的就不用)
	{
	 	zMutex_scope_lock lock(alloc_lock[Size]);
		void *tmp = alloc[Size].alloc0(Size);
		_Node *mFreeNodeList = (_Node *)tmp;
		constructInPlace(mFreeNodeList);
		mFreeNodeList->size = Size;
		//Zebra::logger->debug("申请内存:%p,%p,%u",mFreeNodeList,mFreeNodeList->data,(int)Size);
		return mFreeNodeList->data;
	}
	else
	{
		void *tmp = malloc( Size );
		_Node *mFreeNodeList = (_Node *)tmp;
		constructInPlace(mFreeNodeList);
		mFreeNodeList->size = Size;
		//Zebra::logger->debug("申请内存:%p,%p,%u",mFreeNodeList,mFreeNodeList->data,(int)Size);
		return mFreeNodeList->data;
	}
}

//重载操作符delete
void zMemoryAlloc::operator delete( void* Ptr )
{
	if (!Ptr)
	{
		return;
	}
	_Node* pNod = (_Node*)((char *)Ptr - sizeof(_Node));
	//Zebra::logger->debug("回收内存:%p,%p,%p,%u",pNod,pNod->data,Ptr,pNod->size);
	if(pNod->size < 1024 * 1024 && pNod->size != 0)
	{
		zMutex_scope_lock lock(alloc_lock[pNod->size]);
		alloc[pNod->size].freePtr((char *)pNod);
		return;
	}
	else
	{
		::free( pNod );
	}
}

//重载操作符new[]
void* zMemoryAlloc::operator new[]( size_t Size )
{
	assert(Size != 0);
	Size += sizeof(_Node);
	if(Size <= 1024)//小于1024字节大小的,16字节对齐
	{
	Size = (Size + 0XF) & (0XFFFFFFFF - 0XF);
	}
	else //32字节对齐
	{
		Size = (Size + 0X1F) & (0XFFFFFFFF - 0X1F);
	}
	 
	if(Size < 1024 * 1024)
	{
		zMutex_scope_lock lock(alloc_lock[Size]);
		void *tmp= alloc[Size].alloc0(Size);
		_Node *mFreeNodeList = (_Node *)tmp;
		constructInPlace(mFreeNodeList);
		mFreeNodeList->size = Size;
		//Zebra::logger->debug("申请内存:%p,%p,%u",mFreeNodeList,mFreeNodeList->data,(int)Size);
		return mFreeNodeList->data;
	}
	else
	{
		void *tmp = malloc( Size );
		//Zebra::logger->debug("申请内存:%p,%u",tmp,(int)Size);
		_Node *mFreeNodeList = (_Node *)tmp;
		constructInPlace(mFreeNodeList);
		mFreeNodeList->size = Size;
		return mFreeNodeList->data;
	}
}

//重载delete[]操作符
void zMemoryAlloc::operator delete[]( void* Ptr )
{
	if (!Ptr)
	{
		return;
	}
	_Node* pNod = (_Node*)((char *)Ptr - sizeof(_Node));
	//Zebra::logger->debug("回收内存:%p,%p,%p,%u",pNod,pNod->data,Ptr,pNod->size);
	if(pNod->size < 1024 * 1024 && pNod->size != 0)//如果是小于1024 * 1024 就放到内存池里面(内存是个链表的数组,数组大小为1024 * 1024 +1024,链表为一个个内存块)
	{
		zMutex_scope_lock lock(alloc_lock[pNod->size]);
		alloc[pNod->size].freePtr((char *)pNod);
		return;
	}
	else
	{
		::free( pNod );
	}
}
//重载分配函数
void *zMemoryAlloc::allocator(size_t Size)
{
	assert(Size != 0);
	Size += sizeof(_Node);
	
	if(Size <= 1024)//小于1024字节大小的,16字节对齐
	{
	Size = (Size + 0XF) & (0XFFFFFFFF - 0XF);
	}
	else //32字节对齐
	{
		Size = (Size + 0X1F) & (0XFFFFFFFF - 0X1F);
	}
	
	if(Size < 1024 * 1024)
	{
		zMutex_scope_lock lock(alloc_lock[Size]);//内存池(分配器)申请内存需加锁
		void *tmp= alloc[Size].alloc0(Size);
		_Node *mFreeNodeList = (_Node *)tmp;
		constructInPlace(mFreeNodeList);
		mFreeNodeList->size = Size;
		//Zebra::logger->debug("zMemoryAlloc::allocator申请内存:%p,%p,%u",mFreeNodeList,mFreeNodeList->data,(int)Size);
		return mFreeNodeList->data;
	}
	else
	{
		void *tmp = malloc( Size );
		//Zebra::logger->debug("申请内存:%p,%u",tmp,(int)Size);
		_Node *mFreeNodeList = (_Node *)tmp;
		constructInPlace(mFreeNodeList);
		mFreeNodeList->size = Size;
		return mFreeNodeList->data;
	}
}

void zMemoryAlloc::free(void* Ptr)
{
	if (!Ptr)
	{
		return;
	}
	
	_Node* pNod = (_Node*)((char *)Ptr - sizeof(_Node));
	//Zebra::logger->debug("zMemoryAlloc::free回收内存:%p,%p,%p,%u",pNod,pNod->data,Ptr,pNod->size);
	if(pNod->size < 1024 * 1024 && pNod->size != 0)
	{
		zMutex_scope_lock lock(alloc_lock[pNod->size]);
		alloc[pNod->size].freePtr((char *)pNod);
		return;
	}
	else
	{
		::free( pNod );
	}
}
 

2、使用自定义空间配置器应用实例

typedef std::string string;

template<typename T>
struct basic_ostream: public std::basic_ostream<T, zMemoryAllocator<T> >
{
};

//typedef std::basic_ostream<char, zMemoryAllocator<char> > basic_ostream;   自定义内存分配的字节流类型
template<typename T>
struct basic_istream: public std::basic_istream<T,  zMemoryAllocator<T> >//继承使用内存分配器
{
};
 
template<typename T>
struct vector: public std::vector<T ,zMemoryAllocator<T> >//继承使用内存分配器
{
	vector(){}//构造函数和拷贝构造函数
	vector(int size):std::vector<T ,zMemoryAllocator<T> >(size){}
	vector(const Zebra::vector<T>& v):std::vector<T ,zMemoryAllocator<T> >(v){}
};

template<typename T>
struct list: public std::list<T ,zMemoryAllocator<T> >{};


3、辅助类型和函数

全局函数placement new 封装

template<class T> 
inline void constructInPlace(T  *_Ptr)
{ // construct object at _Ptr with value _Val
new ((void  *)_Ptr) T( );
}


自动锁,方便在复杂函数中锁的使用(自动加锁和自动解锁)

class zMutex_scope_lock : private zNoncopyable
{
public:
	/**
	* \brief 构造函数,对锁进行lock操作
	* \param m 锁的引用
	*/
	zMutex_scope_lock(zMutex &m) : mlock(m) { mlock.lock(); }
	
	/**
	* \brief 析购函数
	* 对锁进行unlock操作
	*/
	~zMutex_scope_lock() { mlock.unlock(); }
	private:
	/**
	* \brief 锁的引用
	*/
	zMutex &mlock;
};







你可能感兴趣的:(自定义通用型空间配置器)