自定义通用型空间配置器

来源:互联网 发布:殷都区水冶镇豫广网络 编辑:程序博客网 时间:2024/05/04 06:19

使用通用型空间配置器,支持提供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 _Valreturn (&_Val);}const_pointer address(const_reference _Val) const{ // return address of nonmutable _Valreturn (&_Val);}void construct(pointer _Ptr, const _Ty& _Val){std::_Construct(_Ptr,_Val);} // deallocate object at _Ptr, ignore sizevoid deallocate(pointer _Ptr, size_type size){zMemoryAlloc::free(_Ptr);}// destroy object at _Ptrvoid destroy(pointer _Ptr){ std::_Destroy(_Ptr);//_Ptr->~_Ty();}// estimate maximum array sizesize_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://重载操作符newstatic 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;}}//重载操作符deletevoid 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 _Valnew ((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;};







原创粉丝点击