[原创]ACE内存分配——不定长数据,不定量个数分配(四)——最终策略
类别:算法
状态:游客可见,可回,会员可关联(精华)
阅读:5406
评论:0
时间:May 27, 2013, 3:06 p.m.
关键字:ACE AVL tree 内存 平衡二叉树
利用[原创]ACE内存分配——不定长数据,不定量个数分配(三)——平衡二叉树实现真正的不定长分配我们实现最终分配方案,见代码:
在_DEBUG模式下,会定时输出各种大小申请次数,可以通过调试确定分配方案,尽量让分配落在定长分配的范围里面。
刚开始调试的时候,反而比没有使用内存管理要耗cpu,后来调整了锁,略胜一点,望高手提供点优化意见。
/*************************************************************** version: 1.0 date: 16/5/2013 17:04 FileName: hwnet_block_allocator.h Author: 丁灵峰 Compiled on: VC.net 2008 ------------------------------------------------------------- Description: Modification history: Other: ------------------------------------------------------------- Copyright (C) 2010 - All Rights Reserved *************************************************************** HW_ACE_ALLOCATOR_MEM_CHICK ****************************************************************/ #if (defined HW_ACE) && (defined HW_ACE_ALLOCATOR) // 使用自定义内存管理 #ifndef _H_hwnet_date_allocator_ #define _H_hwnet_date_allocator_ #include "ace/Malloc.h" #include <ace/Malloc_T.h> #include <boost/shared_ptr.hpp> #include "hwnet_variable_allocator.h" namespace hwnet { template <class ACE_LOCK> class ManageAllocator; template <class ACE_LOCK> class HW_Dynamic_Cached_Allocator : public HW_Allocator { public: /// Create a cached memory pool with @a n_chunks chunks /// each with @a chunk_size size. HW_Dynamic_Cached_Allocator (char* pBuf, size_t n_chunks, size_t chunk_size) : free_list_ (ACE_PURE_FREE_LIST) , chunk_size_(chunk_size) { for (size_t c = 0; c < n_chunks; c++) { void* placement = pBuf + c * chunk_size_; this->free_list_.add (new (placement) ACE_Cached_Mem_Pool_Node<char>); } // Put into free list using placement contructor, no real memory // allocation in the above <new>. } /// Clear things up. ~HW_Dynamic_Cached_Allocator (void) { chunk_size_ = 0; } /** * Get a chunk of memory from free list cache. Note that @a nbytes is * only checked to make sure that it's less or equal to @a chunk_size, * and is otherwise ignored since malloc() always returns a pointer to an * item of @a chunk_size size. */ void *malloc (size_t nbytes = 0) { // Check if size requested fits within pre-determined size. if (nbytes > chunk_size_) return 0; // addr() call is really not absolutely necessary because of the way // ACE_Cached_Mem_Pool_Node's internal structure arranged. return this->free_list_.remove ()->addr (); } /** * Get a chunk of memory from free list cache, giving them * @a initial_value. Note that @a nbytes is only checked to make sure * that it's less or equal to @a chunk_size, and is otherwise ignored * since calloc() always returns a pointer to an item of @a chunk_size. */ virtual void *calloc (size_t nbytes, char initial_value = '\0') { // Check if size requested fits within pre-determined size. if (nbytes > chunk_size_) return 0; // addr() call is really not absolutely necessary because of the way // ACE_Cached_Mem_Pool_Node's internal structure arranged. void *ptr = this->free_list_.remove ()->addr (); if (ptr != 0) ACE_OS::memset (ptr, initial_value, chunk_size_); return ptr; } /// This method is a no-op and just returns 0 since the free list /// only works with fixed sized entities. virtual void *calloc (size_t n_elem, size_t elem_size, char initial_value = '\0') { ACE_NOTSUP_RETURN (0); } /// Return a chunk of memory back to free list cache. void free (void * ptr) { if (ptr != 0) this->free_list_.add ((ACE_Cached_Mem_Pool_Node<char> *) ptr); } /// Return the number of chunks available in the cache. size_t size (void) { return this->free_list_.size(); } private: /// Remember how we allocate the memory in the first place so /// we can clear things up later. //char *pool_; /// Maintain a cached memory free list. We use @c char as template /// parameter, although sizeof(char) is usually less than /// sizeof(void*). Really important is that @a chunk_size /// must be greater or equal to sizeof(void*). ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<char>, ACE_LOCK> free_list_; /// Remember the size of our chunks. size_t chunk_size_; }; template <class ACE_LOCK> class DateNode { public: #ifdef _DEBUG DateNode<ACE_LOCK>(HW_Allocator* pParent, size_t nbytes) #else DateNode<ACE_LOCK>(HW_Allocator* pParent) #endif : m_pParent(pParent) #ifdef _DEBUG , m_flage(0x0101010101010101) , m_nbytes(nbytes) #else #endif { assert(m_pParent); } ~DateNode<ACE_LOCK>() { } public: #ifdef _DEBUG size_t m_flage; // 内存分界标示,是否被越界写检查 size_t m_nbytes; // 实际申请大小 #else #endif HW_Allocator* m_pParent; }; template <class ACE_LOCK> class AllocatorNode : public ACE_New_Allocator { public: union { size_t m_Date;//值 size_t m_uBufSize; // 最小数据内存 }; size_t m_ihgt;//以此节点为根的树的高度 AllocatorNode* m_pFather;//指向父节点的地址 AllocatorNode* m_pLchild;//指向左儿子的地址 AllocatorNode* m_pRchild;//指向右儿子的地址 AllocatorNode* m_pNode;//指向等值节点的地址 //static void Delete(AllocatorNode* pVoid) //{ // if (pVoid) // { // pVoid->~AllocatorNode(); // } // ::free(pVoid); //} //static boost::shared_ptr<AllocatorNode> Create(size_t uBufSum // 一次申请个数 // , size_t MinBufSize // 最小数据内存 // ) //{ // void *ptr = ::malloc(sizeof(AllocatorNode)); // if (ptr) // { // new (ptr) AllocatorNode(uBufSum, MinBufSize); // boost::shared_ptr<AllocatorNode>((AllocatorNode*)ptr, Delete); // } // return boost::shared_ptr<AllocatorNode>(); //} public: AllocatorNode(size_t uBufSum // 一次申请个数 , size_t MinBufSize // 最小数据内存 , ManageAllocator<ACE_LOCK>* pParent ) : m_BufSum(uBufSum) // 一次申请个数 , m_uBufSize(MinBufSize) // 最小数据内存 , m_deqAllocator(NULL) , m_uSizeAllocator(0) , m_uUsedAllocator(0) , m_pParent(pParent) { assert(pParent); m_uSizeAllocator = 1024; m_deqAllocator = (HW_Allocator**)::malloc(sizeof(HW_Allocator*) * m_uSizeAllocator); if (m_deqAllocator) { ACE_OS::memset (m_deqAllocator, 0, sizeof(HW_Allocator*)*m_uSizeAllocator); } else { m_uSizeAllocator = 0; } } ~AllocatorNode(); public: virtual void *malloc (size_t nbytes); virtual void *calloc (size_t nbytes, char initial_value = '\0') { void* ptr = malloc(nbytes); if (ptr) { ACE_OS::memset (ptr, initial_value, nbytes); } return ptr; } virtual void *calloc (size_t n_elem, size_t elem_size, char initial_value = '\0') { return calloc (n_elem * elem_size, initial_value); } // virtual void free (void* ptr) // { // //ACE_GUARD (ACE_LOCK, monitor, this->m_lock); // if (ptr) // { // ((DateNode<ACE_LOCK>*)((char*)ptr - sizeof(DateNode<ACE_LOCK>)))->m_pParent->free(ptr); //#ifdef _DEBUG // std::cout << m_deqAllocator.size() << "(" << m_uBufSize << ")" << std::endl; //#else //#endif // } // } size_t SumTotal() { return m_BufSum*m_uUsedAllocator; } size_t Sum() { return m_uUsedAllocator; } size_t size() { size_t uSize=0; ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, 0); for (size_t i=0 ; i < m_uUsedAllocator ; i++) { uSize += m_BufSum - m_deqAllocator[i]->size(); } return uSize; } // 释放多余空闲块 void FreeEmpty(); private: ACE_LOCK m_lock; size_t m_BufSum; // 一次申请个数 HW_Allocator** m_deqAllocator; size_t m_uSizeAllocator; size_t m_uUsedAllocator; ManageAllocator<ACE_LOCK>* m_pParent; }; template <class ACE_LOCK> class ManageAllocator : public ACE_New_Allocator { // 友元 // 静态属性 #if defined(_DEBUG) || defined(HW_ACE_ALLOCATOR_MEM_CHICK) template <class T> class TreeNodeMem { public: TreeNodeMem(T uMinBufSize, size_t uValue=1) :m_Date(uMinBufSize),m_ihgt(0), m_pFather(NULL), m_pLchild(NULL), m_pRchild(NULL), m_pNode(NULL), m_uValue(uValue){} T m_Date;//值 size_t m_ihgt;//以此节点为根的树的高度 TreeNodeMem* m_pFather;//指向父节点的地址 TreeNodeMem* m_pLchild;//指向左儿子的地址 TreeNodeMem* m_pRchild;//指向右儿子的地址 TreeNodeMem* m_pNode;//指向等值节点的地址 size_t m_uValue; }; #else #endif // 静态函数 public: static void DeleteInstance(ManageAllocator* pVoid) { if (pVoid) { pVoid->~ManageAllocator(); } ::free(pVoid); } static ManageAllocator* CreateInstance(size_t uBufSum // 一次申请个数 , size_t MinBufSize // 最小数据内存 , size_t DateSize // 建议数据初始大小 ) { void *ptr = ::malloc(sizeof(ManageAllocator)); if (ptr) { return new (ptr) ManageAllocator(uBufSum, MinBufSize, DateSize); } return NULL; } // 静态工具 // 接口实现 // 构造于析构 public: virtual ~ManageAllocator(void) { #ifdef _DEBUG std::cout << "类型:"; insubtree(m_avlTreeMenSize.GetRoot()); std::cout << std::endl; #else #endif DeleteAllocatorNode(this->m_avlTree.GetRoot()); } ManageAllocator(size_t uBufSum // 一次申请个数 , size_t MinBufSize // 最小数据内存 , size_t DateSize // 建议数据初始大小 ) : m_Other(uBufSum, 0, this) , m_BufSize(1) // 单位数据内存大小 , m_MenLeng(0) // 单位数据内存大小,几个零,二进制 , m_DateSize(DateSize) // 建议数据初始大小 #ifdef _DEBUG , m_uSim(0) // 已经使用数量 , m_uSimTemp(0) // 输出提示中间间隔 #else #endif { if (MinBufSize < sizeof(char)*AvlDateNodeUnionSize) { MinBufSize = sizeof(char)*AvlDateNodeUnionSize; } MinBufSize += sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize; MinBufSize += sizeof(DateNode<ACE_LOCK>); MinBufSize = ACE_MALLOC_ROUNDUP (MinBufSize, ACE_MALLOC_ALIGN); while (m_BufSize < MinBufSize) { m_BufSize <<= 1; m_MenLeng ++; } } void Create(size_t uBufSum // 一次申请个数 , size_t uBufSize // 单位内存 ) { ACE_GUARD(ACE_LOCK, monitor, this->m_lock); AllocatorNode<ACE_LOCK>* pNode = m_avlTree.Find(uBufSize); if (pNode == NULL) { void* ptr = this->m_Other.malloc(sizeof(AllocatorNode<ACE_LOCK>)); if (ptr) { AllocatorNode<ACE_LOCK>* pNode = new (ptr) AllocatorNode<ACE_LOCK>(uBufSum, uBufSize, this); this->m_avlTree.Insert(pNode); } } } size_t mallocT(size_t nbytes) { // 规范大小为 m_MinBufSize 的整数倍 size_t iSize = (ACE_MALLOC_ROUNDUP (nbytes + (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize), m_BufSize)) >> m_MenLeng; return (iSize << m_MenLeng) - (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize); } size_t mallocSize(size_t nbytes) { AllocatorNode<ACE_LOCK>* pNode = m_avlTree.FindLessOrGreater(nbytes); if (pNode) { return pNode->m_Date; } // 规范大小为 m_MinBufSize 的整数倍 size_t iSize = (ACE_MALLOC_ROUNDUP (nbytes + (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize) + sizeof(DateNode<ACE_LOCK>), m_BufSize)) >> m_MenLeng; return (iSize << m_MenLeng) - (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize) - sizeof(DateNode<ACE_LOCK>); } // 当第一次申请空间,不知道大小的时候,调用,提供建议大小,m_DateSize要经过测试得到 size_t mallocDate() { return m_DateSize; } //size_t mallocSum(size_t iSize=1) //{ // // 规范大小为 m_MinBufSize 的整数倍 // if (iSize < 1) // { // iSize = 1; // } // return (iSize << m_MenLeng) - (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize) - sizeof(DateNode<ACE_LOCK>); //} HW_Allocator* NewAllocator(size_t uBufSum // 一次申请个数 , size_t uBufSize // 单位内存 ) { if (uBufSize == 0) { size_t uSizeHead = ACE_MALLOC_ROUNDUP (uBufSum, AVLTreeVariableAllocator<ACE_LOCK>::s_iHeadSum) >> 2; size_t uSilzeClass = ACE_MALLOC_ROUNDUP (sizeof(AVLTreeVariableAllocator<ACE_LOCK>), ACE_MALLOC_ALIGN); char* pBuf = (char*)::malloc(uSilzeClass + uSizeHead + m_BufSize * uBufSum); if (pBuf) { #ifdef HW_ACE_ALLOCATOR_MEM_CHICK this->AddMen(pBuf, uSilzeClass + uSizeHead + m_BufSize * uBufSum); #else #endif return dynamic_cast<HW_Allocator*>(new (pBuf) AVLTreeVariableAllocator<ACE_LOCK>(pBuf+uSilzeClass, pBuf+uSilzeClass+uSizeHead, uBufSum, m_BufSize, m_MenLeng)); } } else { uBufSize = ACE_MALLOC_ROUNDUP (uBufSize + sizeof(DateNode<ACE_LOCK>), ACE_MALLOC_ALIGN); size_t uSilzeClass = ACE_MALLOC_ROUNDUP (sizeof(HW_Dynamic_Cached_Allocator<ACE_LOCK>), ACE_MALLOC_ALIGN); size_t uSizeTotal = this->mallocT(uSilzeClass + uBufSize * uBufSum); uBufSum = (uSizeTotal-uSilzeClass)/uBufSize; char* pBuf = (char*)this->m_Other.malloc(uSizeTotal); if (pBuf) { #ifdef HW_ACE_ALLOCATOR_MEM_CHICK this->AddMen(pBuf, uSilzeClass + uBufSize * uBufSum); #else #endif return dynamic_cast<HW_Allocator*>(new (pBuf) HW_Dynamic_Cached_Allocator<ACE_LOCK>(pBuf+uSilzeClass, uBufSum, uBufSize)); } } return NULL; } void DelAllocator(HW_Allocator* pAllocator) { pAllocator->~HW_Allocator(); if (dynamic_cast<AVLTreeVariableAllocator<ACE_LOCK>*>(pAllocator) != NULL) { ::free(pAllocator); } else { return this->free(pAllocator); } } // 操作函数 public: virtual void *malloc (size_t nbytes) { // 满足C++的标准规定:当要求的内存大小为0 byte时也应该返回有效的内存地址 //if (nbytes == 0) //{ // return NULL; //} #ifdef _DEBUG { ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL); m_uSimTemp++; TreeNodeMem<size_t>* pNode = m_avlTreeMenSize.Find(nbytes); if (pNode == NULL) { m_uSimTemp = 0; void* ptr = ::malloc(sizeof(TreeNodeMem<size_t>)); if (ptr) { pNode = new (ptr) TreeNodeMem<size_t>(nbytes); this->m_avlTreeMenSize.Insert(pNode); } std::cout << "类型:"; insubtree(m_avlTreeMenSize.GetRoot()); std::cout << std::endl; } else { pNode->m_uValue++; if (m_uSimTemp >= 100000) { m_uSimTemp = 0; std::cout << "类型 \\"; insubtree(m_avlTreeMenSize.GetRoot()); std::cout << std::endl; std::cout << "使用情况 \\"; insubtreeNode(m_avlTree.GetRoot()); std::cout << "其他(" << m_Other.SumTotal()-m_Other.size() << "," << m_Other.size() << ")" << m_Other.Sum(); std::cout << std::endl; } } } #else #endif // 分级 分级在对象建立后创建,以后不加修改,所以不需要加锁 AllocatorNode<ACE_LOCK>* pNode = m_avlTree.FindLessOrGreater(nbytes); if (pNode) { void* ptr = pNode->malloc(nbytes); if (ptr) { #ifdef _DEBUG { ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL); m_uSim++; } #else #endif return ptr; } } // 不定长数据处理 void* ptr = m_Other.malloc(nbytes); if (ptr) { #ifdef _DEBUG ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL); m_uSim++; #else #endif } else { std::cerr << "分配失败!"; } return ptr; } virtual void *calloc (size_t nbytes, char initial_value = '\0') { void* ptr = malloc(nbytes); if (ptr) { ACE_OS::memset (ptr, initial_value, nbytes); } return ptr; } virtual void *calloc (size_t n_elem, size_t elem_size, char initial_value = '\0') { return calloc (n_elem * elem_size, initial_value); } virtual void free (void* ptr) { #ifdef _DEBUG assert(m_uSim > 0); #else #endif if (ptr) { DateNode<ACE_LOCK>* pNode = (DateNode<ACE_LOCK>*)((char*)ptr - sizeof(DateNode<ACE_LOCK>)); pNode->m_pParent->free((char*)ptr - sizeof(DateNode<ACE_LOCK>)); #ifdef _DEBUG ACE_GUARD (ACE_LOCK, monitor, this->m_lock); m_uSim--; #else #endif } } #ifdef HW_ACE_ALLOCATOR_MEM_CHICK void AddMen(void* uPose, size_t uSize) { ACE_GUARD (ACE_LOCK, monitor, this->m_lock); TreeNodeMem<void*>* pNode = this->m_avlTreeMenChick.FindLessOrGreater(uPose, false); if (pNode) { if ((pNode->m_Date <= uPose) && ((char*)uPose+uSize <= (char*)pNode->m_Date+pNode->m_uValue)) { return ; } } void* ptr = ::malloc(sizeof(TreeNodeMem<void*>)); if (ptr) { pNode = new (ptr) TreeNodeMem<void*>(uPose, uSize); this->m_avlTreeMenChick.Insert(pNode); } #ifdef _DEBUG std::cout << "内存添加:" << uPose << ",\t" << (void*)((char*)uPose+uSize) << std::endl; #endif } void DelMen(void* uPose, size_t uSize) { ACE_GUARD (ACE_LOCK, monitor, this->m_lock); TreeNodeMem<void*>* pNode = this->m_avlTreeMenChick.Find(uPose); if (pNode == NULL) { return ; } if ((pNode->m_Date != uPose) || (pNode->m_uValue != uSize)) { return ; } this->m_avlTreeMenChick.Delete(pNode); pNode->~TreeNodeMem<void*>(); ::free(pNode); #ifdef _DEBUG std::cout << "内存删除:" << uPose << ",\t" << (void*)((char*)uPose+uSize) << std::endl; #else #endif } virtual void free_chick (void* ptr) { ACE_GUARD (ACE_LOCK, monitor, this->m_lock); TreeNodeMem<void*>* pNode = this->m_avlTreeMenChick.FindLessOrGreater((char*)ptr, false); if (pNode) { if ((pNode->m_Date < ptr) && ((char*)ptr <= (char*)pNode->m_Date+pNode->m_uValue)) { return free(ptr); } } #ifdef _DEBUG std::cout << "删除:" << ptr << std::endl; #else #endif pNode = this->m_avlTreeMenChick.FindLessOrGreater((char*)ptr, false); if (pNode) { if ((pNode->m_Date < ptr) && ((char*)ptr <= (char*)pNode->m_Date+pNode->m_uValue)) { return free(ptr); } } return ::free(ptr); } #else #endif #ifdef _DEBUG /// Return the number of chunks available in the cache. size_t Size (void) { return m_uSim; } #else #endif //中序遍历函数 void DeleteAllocatorNode(AllocatorNode<ACE_LOCK>* pNode) { if(pNode==NULL) return; DeleteAllocatorNode(pNode->m_pLchild);//先遍历左子树 pNode->~AllocatorNode<ACE_LOCK>(); this->m_Other.free(pNode); DeleteAllocatorNode(pNode->m_pRchild);//再遍历右子树 } //中序遍历函数 void insubtreeFreeEmpty(AllocatorNode<ACE_LOCK>* pNode) { if(pNode==NULL) return; insubtreeFreeEmpty(pNode->m_pLchild);//先遍历左子树 pNode->FreeEmpty(); insubtreeFreeEmpty(pNode->m_pRchild);//再遍历右子树 } // 释放多余空闲块 void FreeEmpty() { insubtreeFreeEmpty(m_avlTree.GetRoot()); // 不定长数据处理 m_Other.FreeEmpty(); } // 工具函数 private: protected: #ifdef _DEBUG //中序遍历函数 void insubtree(TreeNodeMem<size_t>* pNode) { if(pNode==NULL) return; insubtree(pNode->m_pLchild);//先遍历左子树 std::cout << pNode->m_Date << "(" << pNode->m_uValue << ") "; insubtree(pNode->m_pRchild);//再遍历右子树 } //中序遍历函数 void insubtreeNode(AllocatorNode<ACE_LOCK>* pNode) { if(pNode==NULL) return; insubtreeNode(pNode->m_pLchild);//先遍历左子树 std::cout << pNode->m_Date << "(" << pNode->SumTotal()-pNode->size() << "," << pNode->size() << ")" << pNode->Sum() << " "; insubtreeNode(pNode->m_pRchild);//再遍历右子树 } #else #endif // 禁止 private: ManageAllocator(const ManageAllocator&); //复制构造 ManageAllocator & operator= (const ManageAllocator&); // 等于重载 // 属性 public: protected: ACE_LOCK m_lock; AVLTree<AllocatorNode<ACE_LOCK>, size_t> m_avlTree; // 平衡二叉树 AllocatorNode<ACE_LOCK> m_Other; size_t m_BufSize; // 单位数据内存大小 size_t m_MenLeng; // 单位数据内存大小,几个零,二进制 size_t m_DateSize; // 建议数据初始大小 #ifdef _DEBUG size_t m_uSim; // 已经使用数量 size_t m_uSimTemp; // 输出提示中间间隔 AVLTree<TreeNodeMem<size_t>, size_t> m_avlTreeMenSize; // 平衡二叉树 用于记录申请个数 #else #endif #ifdef HW_ACE_ALLOCATOR_MEM_CHICK AVLTree<TreeNodeMem<void*>, void*> m_avlTreeMenChick; // 平衡二叉树 用于类型检查 #else #endif }; template <class ACE_LOCK> AllocatorNode<ACE_LOCK>::~AllocatorNode() { for (size_t i=0 ; i < m_uUsedAllocator ; i++) { this->m_pParent->DelAllocator(m_deqAllocator[i]); } ::free(m_deqAllocator); } // 释放多余空闲块 template <class ACE_LOCK> void AllocatorNode<ACE_LOCK>::FreeEmpty() { ACE_GUARD (ACE_LOCK, monitor, this->m_lock); bool bFlage=true; // 我们只释放第二块 for (size_t i=0 ; i < m_uUsedAllocator ; i++) { if (m_BufSum == m_deqAllocator[i]->size()) { if (bFlage) { this->m_pParent->DelAllocator(m_deqAllocator[i]); m_deqAllocator[i] = NULL; for (size_t j=i ; j < m_uUsedAllocator ; j++) { m_deqAllocator[j] = m_deqAllocator[j+1]; } m_uUsedAllocator--; } else { bFlage = true; } } } } template <class ACE_LOCK> void* AllocatorNode<ACE_LOCK>::malloc (size_t nbytes) { // 还有空闲 if (m_uUsedAllocator > 0) { for (int i=m_uUsedAllocator/2; i>=0; i--) { HW_Allocator* pAllocator = m_deqAllocator[0]; if ((pAllocator) && (pAllocator->size() > 0)) { void* ptr = pAllocator->malloc(nbytes); if (ptr) { #ifdef _DEBUG new (ptr) DateNode<ACE_LOCK>(dynamic_cast<HW_Allocator*>(pAllocator), nbytes); #else new (ptr) DateNode<ACE_LOCK>(dynamic_cast<HW_Allocator*>(pAllocator)); #endif return (char*)ptr + sizeof(DateNode<ACE_LOCK>); } } ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL); if ((pAllocator) && (pAllocator == m_deqAllocator[0])) { for (size_t i=0 ; i < m_uUsedAllocator ; i++) { m_deqAllocator[i] = m_deqAllocator[i+1]; } m_deqAllocator[m_uUsedAllocator-1] = pAllocator; } } } // 重新分配 if (m_uSizeAllocator < m_uUsedAllocator+1) { size_t uSizeAllocator = m_uSizeAllocator + 1024; HW_Allocator** deqAllocator = (HW_Allocator**)::malloc(sizeof(HW_Allocator*) * uSizeAllocator); if (deqAllocator) { ACE_OS::memset (deqAllocator, 0, sizeof(HW_Allocator*)*uSizeAllocator); for (size_t i=0 ; i < m_uUsedAllocator ; i++) { deqAllocator[i] = m_deqAllocator[i]; } ::free(m_deqAllocator); m_deqAllocator = deqAllocator; m_uSizeAllocator = uSizeAllocator; } else { return NULL; } } HW_Allocator* pAllocator = this->m_pParent->NewAllocator(m_BufSum, m_uBufSize); if (pAllocator) { { ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL); m_deqAllocator[m_uUsedAllocator] = pAllocator; m_uUsedAllocator++; } void* ptr = pAllocator->malloc(nbytes); if (ptr) { #ifdef _DEBUG new (ptr) DateNode<ACE_LOCK>(dynamic_cast<HW_Allocator*>(pAllocator), nbytes); #else new (ptr) DateNode<ACE_LOCK>(dynamic_cast<HW_Allocator*>(pAllocator)); #endif return (char*)ptr + sizeof(DateNode<ACE_LOCK>); } } return NULL; } } #endif // #ifndef _H_hwnet_date_allocator_ #endif // HW_ACE HW_ACE_ALLOCATOR //使用自定义内存管理
使用方法:
std::set<size_t> setMinSize; setMinSize.insert(40); setMinSize.insert(1024); boost::shared_ptr<ManageAllocator<ACE_SYNCH_RECURSIVE_MUTEX> > Block::gPManageBlockAllocator; gPManageBlockAllocator.reset(new ManageAllocator<ACE_SYNCH_RECURSIVE_MUTEX>(setMinSize, 1024, 1024*16)); ACE_Allocator::instance (dynamic_cast<ACE_Allocator*>(gPManageBlockAllocator.get()));
操作: