固定的,高效的内存池实现,代码如下:
#ifndef __FIXOBJPOOL_H__#define __FIXOBJPOOL_H__
//// 高效、固定大小、小数量内存池,思想来自LOKI//#include "stdafx.h"
namespace loki{ template <int blocksize, unsigned short blockcount> class CFixMemPool { typedef unsigned short blockcount_type; public: CFixMemPool() { // 空间大小限制 GNASSERT(blocksize >= sizeof(blockcount_type));
m_poBuff = new char[blocksize * blockcount]; GNASSERT(m_poBuff); // 作标记 blockcount_type i = 0; for (char* p = m_poBuff; i < blockcount; p += blocksize) { *(blockcount_type*)p = ++i; }
m_nFreeBlckCount = blockcount; m_tCurAvailableBlock = 0; } virtual ~CFixMemPool() { if (m_poBuff) { delete [] m_poBuff; m_poBuff = NULL; } }
// 获取内存块 char* Allocate(int nSize) { GNASSERT(nSize == blocksize);
if (m_nFreeBlckCount <= 0) { goto ACK; }
char* poBuff = m_poBuff + (m_tCurAvailableBlock * blocksize); GNASSERT(poBuff); m_tCurAvailableBlock = *(blockcount_type*)poBuff;
m_nFreeBlckCount--; GNASSERT(m_nFreeBlckCount >= 0); return poBuff; ACK: return NULL; }
// 释放内存块 void Dellocate(char* poBuff) { if (NULL == poBuff) { return; }
*(blockcount_type*)poBuff = m_tCurAvailableBlock; m_tCurAvailableBlock = static_cast<blockcount_type>(static_cast<int>(poBuff - m_poBuff) / blocksize); GNASSERT(m_tCurAvailableBlock < blocksize);
m_nFreeBlckCount++; GNASSERT(m_nFreeBlckCount >= 0); }
protected: char* m_poBuff; // 内存块区域 int m_nFreeBlckCount; // 自由块数量 blockcount_type m_tCurAvailableBlock; // 当前可分配的自由块 };}
#endif
上述代码有如下的应用:
1,全局的内存池获取,代码如下:
#ifndef __GLOBALMEMPOOLMGR_H__#define __GLOBALMEMPOOLMGR_H__
#include "singleton.h"#include "fixmempool.h"#include "noncopy.h"using namespace loki;
//// 内存管理模块//class CGlobalMemPoolCtrl : public Gavin::CNonCopy{ DECLARE_SINGLETON(CGlobalMemPoolCtrl);private: CGlobalMemPoolCtrl() {} ~CGlobalMemPoolCtrl() {}
public: // 内存块的操作,获取和释放 template<int BLOCKSIZE, unsigned short BLOCKCOUNT> inline void OptMem(char*& poBuff, bool bFetch = false) { // 认真理解下面的代码,非常棒 static CFixMemPool<BLOCKSIZE, BLOCKCOUNT> s_oFixeObjPool; if (bFetch) { poBuff = s_oFixeObjPool.Allocate(BLOCKSIZE); } else { s_oFixeObjPool.Dellocate(poBuff); } }};
#define GLOBALMEMCTRL CGlobalMemPoolCtrl::Instance()
//// 获取内存, 自动释放//template<int BLOCKSIZE, unsigned short BLOCKCOUNT>struct SShellGlobalMem{public: inline SShellGlobalMem() { GLOBALMEMCTRL->OptMem<BLOCKSIZE, BLOCKCOUNT>(m_poBuff, true); } inline ~SShellGlobalMem() { GLOBALMEMCTRL->OptMem<BLOCKSIZE, BLOCKCOUNT>(m_poBuff, false); }
char* GetData() { return m_poBuff; } int GetSize() { return BLOCKSIZE; }
private: char* m_poBuff;};
#endif
2,固定大小的对象池分配器,代码如下:
#ifndef __FIXOBJALLOCATOR_H__#define __FIXOBJALLOCATOR_H__
//// 固定的,高效对象分配池//#include "fixmempool.h"#include "commontraints.h"#include <new>using namespace loki;
template<typename T, int SIZE>class CFixObjAllocator : public Gavin::CCommonTraits<T>{public: CFixObjAllocator() {} virtual ~CFixObjAllocator() {}
public: // 获取对象 value_type* FetchObj() { char* poBuff = m_oFixMemPool.Allocate(sizeof(value_type)); if (poBuff) { new (poBuff) value_type(); return reinterpret_cast<value_type*>(poBuff); } else { return NULL; } }
// 释放对象 void ReleaseObj(value_type* poT) { if (NULL == poT) { return; } poT->~value_type(); m_oFixMemPool.Dellocate(reinterpret_cast<char*>(poT)); }
protected: CFixMemPool<sizeof(value_type), SIZE> m_oFixMemPool;};
#endif