使用通用型空间配置器,支持提供stl容器的空间分配功能。
设计上:
(1)自定义空间配置器使用内存池管理器来分配内存。
(2)内存池管理器包含1024*1024 + 1024 个内存池的数组(附带1024*1024 + 1024 个锁,单逻辑线程的可以不使用)。对应不同的内存分配需求大小就寻找对应的内存池来分配(大小限制在1024*1024 字节以内),每个内存池使用链表数据结构。
下面是自定义空间配置器定义代码:
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; }
内存池管理器设计
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 ); } }
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> >{};
全局函数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; };