固定的,高效的内存池实现,代码如下:
#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