前些日子做服务器方面的项目,感觉服务器需要长期的稳定的运行;内存的管理是至关重要的,特别释Windows程序的内存管理,服务器在性能方面服务器由于处理的事物比较多,效率方面也是要考虑的一个因素,对一些对内存访问频繁服务器程序,我想我们也不得不考虑如何在内存分配上提高服务器的效率,同时又不出现内存泄露、内存碎片和没有内存充分的利用的问题。常规的动态分配内存,由于频繁的调用系统内核进行内存分配,使得每次分配和释放都会引起系统中断响应,这里是不应该浪费的CPU时间;同时如果这样频繁的释放和分配肯定会出现内存碎片,同样又会触发系统的碎片整理,这个更加浪费CPU时间了;还有一个很重要的原因那就是内存的换页,我们知道操作系统只把局部的内存加载的寄存器中,当访问的地址的内存不在寄存器中时,就会产生内存换页,执行一些换页的操作,这个也非常浪费CPU的时间。为了解决这些问题,我想采用静态的分配内存,自己管理一部分内存不是为好办法,即可解决上面的三个问题。在这里我根据个人应用写了一个内存池类库,感觉还不错,如有任何使用问题可以联系我,QQ176632581,原与所有爱好软件的朋友分享。
/************************************************************************
* 版权所有 (C)2008, 陈彦旭
*
* 文件名称: MemPool.h
* 内容摘要: 内存池类 内存的分配和释放
* 其它说明:
* 当前版本: 1.0.0.0
* 作 者: 陈彦旭
* 完成日期: 2008年03月14日
************************************************************************/
#ifndef _MEMORY_POOL
#define _MEMORY_POOL
#include "MyMutex.h"
#include "MemBlock.h"
class CMemPool
{
public:
CMemPool( DWORD dMemSize = 10 * 1024 * 1024, unsigned int uBlockCount = 10,
unsigned int uUnitCount = 1024, unsigned int uUnitSize = 1024 );
virtual ~CMemPool();
public:
BOOL InitMemPool();
BOOL UnitMemPool();
BYTE* Alloc( unsigned int uMemSize );
BOOL Free( BYTE* pMem );
protected:
BOOL InitAllBlock();
BOOL UnitAllBlock();
CMemBlock* FindBlock( BYTE* pMem );
unsigned int CalcUnitCount( unsigned int uMemSize );
public:
inline void SetBlockCount( unsigned int uCount ) { m_BlockCount = uCount; };
inline void SetUnitCount( unsigned int uCount ) { m_UnitCount = uCount; };
inline void SetUnitSize( unsigned int uSize ) { m_UnitSize = uSize; };
inline unsigned int GetBlockCount() const { return m_BlockCount; };
inline unsigned int GetUnitCount() const { return m_UnitCount; };
inline unsigned int GetUnitSize() const { return m_UnitSize; };
private:
BYTE* m_pMem;
unsigned int m_BlockCount;
unsigned int m_UnitCount;
unsigned int m_UnitSize;
DWORD m_MemSize;
private:
CMyMutex m_Mutex;
CMemBlock* m_pBlockHead;
};
#endif
#include "stdafx.h"
#include "MemPool.h"
CMemPool::CMemPool( DWORD dMemSize, unsigned int uBlockCount,
unsigned int uUnitCount, unsigned int uUnitSize)
:m_BlockCount(uBlockCount),m_MemSize(dMemSize),m_UnitSize(uUnitSize),
m_UnitCount(uUnitCount)
{
}
CMemPool::~CMemPool()
{
}
BOOL CMemPool::InitMemPool()
{
CUseMutex mutex(&this->m_Mutex);
try
{
m_MemSize = this->GetUnitSize() * this->GetUnitCount() * this->GetBlockCount();
this->m_pMem = ( BYTE* )malloc(m_MemSize);
this->m_pBlockHead = new CMemBlock[this->GetBlockCount()];
for (int i=0; i<this->GetBlockCount(); i++)
{
if (i == (this->GetBlockCount() - 1))
m_pBlockHead[i].SetNextBlock(NULL);
else
m_pBlockHead[i].SetNextBlock(&m_pBlockHead[i+1]);
m_pBlockHead[i].SetUnitSize(this->GetUnitSize());
m_pBlockHead[i].SetBlockP(this->m_pMem + this->GetUnitSize() * this->GetUnitCount() * i);
m_pBlockHead[i].SetBlockSize(this->GetUnitCount());
}
this->InitAllBlock();
}
catch (...)
{
}
return TRUE;
}
BOOL CMemPool::UnitMemPool()
{
CUseMutex mutex(&this->m_Mutex);
this->UnitAllBlock();
free(this->m_pMem);
this->m_pMem = NULL;
delete []this->m_pBlockHead;
this->m_pBlockHead = NULL;
return TRUE;
}
BYTE* CMemPool::Alloc( unsigned int uMemSize )
{
CUseMutex mutex(&this->m_Mutex);
CMemBlock* pBlock = this->m_pBlockHead;
int nCount = CalcUnitCount(uMemSize);
while (NULL != pBlock)
{
if (nCount < pBlock->GetFreeCount())
{
BYTE* pByte = pBlock->Alloc(nCount);
if (NULL != pByte)
return pByte;
}
pBlock = pBlock->GetNextBlock();
}
return NULL;
}
BOOL CMemPool::Free( BYTE* pMem )
{
CUseMutex mutex(&this->m_Mutex);
CMemBlock* pBlock = this->FindBlock(pMem);
if (NULL != pBlock)
{
pBlock->Free(pMem);
return TRUE;
}
return FALSE;
}
unsigned int CMemPool::CalcUnitCount( unsigned int uMemSize )
{
unsigned int nCount = 0;
nCount = uMemSize / this->GetUnitSize();
if (uMemSize % this->GetUnitSize())
{
nCount++;
}
return nCount;
}
BOOL CMemPool::InitAllBlock()
{
CMemBlock* pBlock = this->m_pBlockHead;
while (NULL != pBlock)
{
pBlock->InitBlock();
pBlock = pBlock->GetNextBlock();
}
return TRUE;
}
BOOL CMemPool::UnitAllBlock()
{
CMemBlock* pBlock = this->m_pBlockHead;
while (NULL != pBlock)
{
pBlock->UnitBlock();
pBlock = pBlock->GetNextBlock();
}
return TRUE;
}
CMemBlock* CMemPool::FindBlock( BYTE* pMem )
{
CMemBlock* pBlock = this->m_pBlockHead;
while (NULL != pBlock)
{
if (NULL != pBlock->GetNextBlock())
{
if ( (pMem >= pBlock->GetBlockP()) && (pMem < pBlock->GetNextBlock()->GetBlockP()) )
return pBlock;
}
else if ((pMem >= pBlock->GetBlockP()) &&
(pMem < (m_pMem + this->GetBlockCount()*this->GetUnitCount()*this->GetUnitSize()) ))
{
return pBlock;
}
pBlock = pBlock->GetNextBlock();
}
return NULL;
}
/************************************************************************
* 版权所有 (C)2008, 陈彦旭
*
* 文件名称: MemUnit.h
* 内容摘要: 内存页面类
* 其它说明:
* 当前版本: 1.0.0.0
* 作 者: 陈彦旭
* 完成日期: 2008年03月14日
************************************************************************/
#ifndef _MEMORY_UNIT
#define _MEMORY_UNIT
class CMemUnit
{
public:
CMemUnit( BYTE* pUnit = NULL, unsigned int uUnitSize = 16, BOOL bFree = TRUE );
virtual ~CMemUnit();
public:
inline void SetFreeState( BOOL bFree ) { m_bFree = bFree; };
inline BOOL IsFree() { return m_bFree; };
inline void SetUsedCount( unsigned int nCount ) { m_UsedCount = nCount; };
inline unsigned int GetUsedCount() { return m_UsedCount; };
inline void SetUnitP( BYTE* pUnit ) { m_pUnit = pUnit; };
inline BYTE* GetUnitP() { return m_pUnit; };
inline void SetNextUnit( CMemUnit* pUnit ) { m_pNextUnit = pUnit; };
inline CMemUnit* GetNextUnit() { return m_pNextUnit; };
inline void SetUnitSize( unsigned int nUnitSize ) { m_UnitSize = nUnitSize; };
inline unsigned int GetUnitSize() { return m_UnitSize; };
private:
BYTE* m_pUnit;
unsigned int m_UnitSize;
unsigned int m_UsedCount;
BOOL m_bFree;
CMemUnit* m_pNextUnit;
CMemUnit* m_pFirstUnit;
};
#endif
#include "stdafx.h"
#include "MemUnit.h"
CMemUnit::CMemUnit( BYTE* pUnit, unsigned int uUnitSize, BOOL bFree)
:m_bFree(bFree),m_pUnit(pUnit),m_UnitSize(uUnitSize),m_UsedCount(0),m_pNextUnit(NULL)
{
}
CMemUnit::~CMemUnit()
{
}
/************************************************************************
* 版权所有 (C)2008, 陈彦旭
*
* 文件名称: MemBlock.h
* 内容摘要: 内存块管理和操作类
* 其它说明:
* 当前版本: 1.0.0.0
* 作 者: 陈彦旭
* 完成日期: 2008年03月14日
************************************************************************/
#ifndef _MEMORY_BLOCK
#define _MEMORY_BLOCK
class CMemUnit;
class CMemBlock
{
public:
CMemBlock( BYTE* pBlock = NULL, unsigned int nSize = 0 );
virtual ~CMemBlock();
public:
inline unsigned int GetFreeCount() { return m_nFree; };
inline void SetFreeCount( unsigned int nFree ) { m_nFree = nFree; };
inline void SetBlockP( BYTE* pBlock ) { m_pBlock = pBlock; };
inline BYTE* GetBlockP() { return m_pBlock; };
inline void SetBlockSize( unsigned int nSize = 0 ) { m_nSize = nSize; m_nFree = nSize; };
inline unsigned int GetBlockSize() { return m_nSize; };
inline void SetNextBlock( CMemBlock* pNextBlock ) { m_pNextBlock = pNextBlock; };
inline CMemBlock* GetNextBlock() { return m_pNextBlock; };
inline void SetUnitSize( unsigned int nUnitSize = 0 ) { m_UnitSize = nUnitSize; };
inline unsigned int GetUnitSize() { return m_UnitSize; };
public:
BOOL InitBlock();
BOOL UnitBlock();
BYTE* Alloc( unsigned int uUnitCount );
BOOL Free( BYTE* pUnit );
private:
BYTE* m_pBlock;
unsigned int m_nFree;
unsigned int m_nSize;
unsigned int m_UnitSize;
CMemUnit* m_pFirstFreeUnit;
CMemBlock* m_pNextBlock;
CMemUnit* m_pFirstUnit;
};
#endif
#include "stdafx.h"
#include "MemBlock.h"
#include "MemUnit.h"
CMemBlock::CMemBlock( BYTE* pBlock, unsigned int nSize)
:m_pBlock(pBlock),m_nFree(0),m_nSize(nSize),m_pFirstFreeUnit(NULL),
m_pNextBlock(NULL),m_pFirstUnit(NULL)
{
}
CMemBlock::~CMemBlock()
{
}
BOOL CMemBlock::InitBlock()
{
m_pFirstUnit = new CMemUnit[this->GetBlockSize()];
for (int i=0; i<this->GetBlockSize(); i++)
{
m_pFirstUnit[i].SetUnitP(this->GetBlockP() + i*this->GetUnitSize());
if (i == (this->GetBlockSize() - 1))
m_pFirstUnit[i].SetNextUnit(NULL);
else
m_pFirstUnit[i].SetNextUnit(&m_pFirstUnit[i+1]);
m_pFirstUnit[i].SetUnitSize(this->GetUnitSize());
}
return TRUE;
}
BOOL CMemBlock::UnitBlock()
{
delete []m_pFirstUnit;
m_pFirstUnit = NULL;
return TRUE;
}
BYTE* CMemBlock::Alloc( unsigned int uUnitCount )
{
CMemUnit* pUnit = this->m_pFirstUnit;
CMemUnit* pTemp = NULL;
BYTE* pMem = NULL;
int nCount = 0;
while (NULL != pUnit)
{
pTemp = pUnit;
while (pUnit->IsFree())
{
nCount ++;
pUnit = pUnit->GetNextUnit();
if ( uUnitCount <= nCount)
{
this->SetFreeCount(this->GetFreeCount() - nCount);
pTemp->SetUsedCount(uUnitCount);
pMem = pTemp->GetUnitP();
while (pTemp != pUnit)
{
pTemp->SetFreeState(FALSE);
pTemp = pTemp->GetNextUnit();
}
return pMem;
}
}
pUnit = pUnit->GetNextUnit();
}
return NULL;
}
BOOL CMemBlock::Free( BYTE* pUnit )
{
CMemUnit* pMemUnit = m_pFirstUnit;
CMemUnit* pTemp = NULL;
while (NULL != pMemUnit)
{
if (pUnit == pMemUnit->GetUnitP())
{
pTemp = pMemUnit;
this->SetFreeCount(this->GetFreeCount() + pMemUnit->GetUsedCount());
for (int i=0; i<pMemUnit->GetUsedCount(); i++)
{
pTemp->SetFreeState(TRUE);
pTemp = pTemp->GetNextUnit();
}
return TRUE;
}
pMemUnit = pMemUnit->GetNextUnit();
}
return FALSE;
}
/************************************************************************
* 版权所有 (C)2008, 陈彦旭
*
* 文件名称: MemUser.h
* 内容摘要: 内存池使用类
* 其它说明:
* 当前版本: 1.0.0.0
* 作 者: 陈彦旭
* 完成日期: 2008年03月14日
************************************************************************/
#ifndef _MEMORY_USER
#define _MEMORY_USER
#define _AOTU_REALSE
class CMemPool;
class CMemUser
{
public:
CMemUser( CMemPool* pMemPool = NULL, unsigned int nSize = 0, BYTE* pBuf = NULL, DWORD nType = 0 );
virtual ~CMemUser();
public:
BOOL ReleaseBuf();
inline BYTE* GetBuf() { return m_pBuf; };
inline unsigned int GetBufSize() { return m_BufSize; };
inline DWORD GetType() { return m_Type; };
private:
unsigned int m_BufSize;
BYTE* m_pBuf;
DWORD m_Type;
CMemPool* m_pMemPool;
};
#endif
#include "stdafx.h"
#include "MemPool.h"
#include "MemUser.h"
CMemUser::CMemUser( CMemPool* pMemPool, unsigned int nSize, BYTE* pBuf, DWORD nType )
:m_pMemPool(pMemPool),m_BufSize(nSize),m_pBuf(NULL),m_Type(nType)
{
if (NULL != this->m_pMemPool)
{
this->m_pBuf = this->m_pMemPool->Alloc(this->m_BufSize);
if (NULL != m_pBuf)
{
memset(m_pBuf, 0, this->m_BufSize);
memcpy(m_pBuf, pBuf, m_BufSize);
}
}
}
CMemUser::~CMemUser()
{
#ifdef _AOTU_REALSE
if (NULL != this->m_pMemPool)
this->m_pMemPool->Free(this->m_pBuf);
#endif
}
BOOL CMemUser::ReleaseBuf()
{
if (NULL != this->m_pMemPool)
{
this->m_pMemPool->Free(this->m_pBuf);
m_pBuf = NULL;
this->m_BufSize = 0;
}
return TRUE;
}