一个内存池代码

最近做服务器,需要把数千个客户端上发的数据保存起来;保存数据所使用的缓冲区,是从一个内存池里面取得的;客户端上发的数据,长度从几十字节至三四 k 不等(按照协议,数据长度最大为4k);如果内存池中的每片缓冲区的长度大小都使用4k,会造成空间浪费,因为客户端就算只上发几个字节的数据,也会占用一片4k的缓冲区;想了一下,就做了下面这个内存池来避免空间浪费;里面使用了8块大内存,每块内存依次按照 32字节 至 4k 为单位长度,细分为若干个区域,并使用8个堆栈来保存这些区域的地址;收到客户端数据以后,根据数据长度从内存池里面取一片合适长度的缓冲区来保存数据。。。。。。

 

MemoryPool.h  

#ifndef __MEMORYPOOL_H__
#define __MEMORYPOOL_H__

#include <Windows.h>
#include "stack.h"  //代码见
http://blog.csdn.net/firebird321/archive/2010/04/27/5532985.aspx

class CMemoryPool
{
 CStack< char* >*   m_pStackBufferPool;

 DWORD      m_dwPerSize;   //内存池的元素大小

 DWORD      m_dwCount;    //内存池的元素个数

 char*      m_pBuffer;    //内存池起始地址

 VOID      AllocBuffer( VOID );

 VOID      FreeBuffer( VOID ); 
public:
 CMemoryPool( DWORD dwCount, DWORD dwPerSize );

 virtual ~CMemoryPool( VOID );

 // 从相应的内存池中取得一片内存
 char*      GetBufferNode( VOID );

 // 将使用的内存片放回内存池
 BOOL      AddBufferNode( char* pBuf );
};

#endif

 

 

MemoryPool.cpp 

#include "MemoryPool.h"

class CMemoryBadInit
{
public:
 CMemoryBadInit() {}
};

CMemoryPool::CMemoryPool( DWORD dwCount, DWORD dwPerSize )
{
 m_pBuffer = NULL;

 m_pStackBufferPool =  NULL;

 m_dwCount = dwCount;

 m_dwPerSize = dwPerSize;

 AllocBuffer();
}

CMemoryPool::~CMemoryPool( VOID )
{
 FreeBuffer();
}

VOID CMemoryPool::AllocBuffer( VOID )
{
 m_pBuffer = new char[ m_dwCount * m_dwPerSize ];

 if ( NULL == m_pBuffer )
 {
  throw CMemoryBadInit();
  return;
 }

 m_pStackBufferPool = new CStack<char*>( m_dwCount ); 
 if ( NULL == m_pStackBufferPool )
 {
  throw CMemoryBadInit();
  return;
 } 

 for ( DWORD i=0; i<m_dwCount; i++ )
 {
  m_pStackBufferPool->push( m_pBuffer + i * m_dwPerSize );
 }
}

VOID CMemoryPool::FreeBuffer( VOID )

 if ( NULL != m_pStackBufferPool )
 {
  delete m_pStackBufferPool;
 }

 if ( NULL != m_pBuffer )
 {
  delete [] m_pBuffer;
 } 
}

char* CMemoryPool::GetBufferNode( VOID )
{
 char* p = NULL;

 if ( 0 == m_pStackBufferPool->size() )
 {
  return p;
 }

 p = m_pStackBufferPool->top();

 m_pStackBufferPool->pop();

 return p;
}

BOOL CMemoryPool::AddBufferNode( char* pBuf )
{
 if ( NULL==m_pBuffer || NULL==m_pStackBufferPool || NULL==pBuf )
 {
  return FALSE;
 }

 if ( ( pBuf < m_pBuffer ) && ( pBuf > ( m_pBuffer + m_dwCount * m_dwPerSize ) ) )
 {
  return FALSE;
 }

 m_pStackBufferPool->push( pBuf );

 return TRUE;
}

MemoryManager.h

#ifndef __MEMORYMANAGER_H__
#define __MEMORYMANAGER_H__

#include <Windows.h>
#include "MemoryPool.h"

enum BUFFER_LENGTH_TYPE { DATA_LENGTH_32, DATA_LENGTH_64, DATA_LENGTH_128, DATA_LENGTH_256, DATA_LENGTH_512,
     DATA_LENGTH_1024, DATA_LENGTH_2048, DATA_LENGTH_4096, DATA_LENGTH_ERROR };

class CMemoryManager
{
protected:
 CMemoryPool*    m_pMemoryPool_32;
 CMemoryPool*    m_pMemoryPool_64;
 CMemoryPool*    m_pMemoryPool_128;
 CMemoryPool*    m_pMemoryPool_256;
 CMemoryPool*    m_pMemoryPool_512;
 CMemoryPool*    m_pMemoryPool_1024;
 CMemoryPool*    m_pMemoryPool_2048;
 CMemoryPool*    m_pMemoryPool_4096;

 VOID      AllocBuffer( VOID );

 VOID      FreeBuffer( VOID ); 

 // 从相应的内存池中取得一片内存
 char*      GetBuffer( DWORD dwType );

public:
 CMemoryManager( VOID );

 virtual ~CMemoryManager( VOID );

 char* GetBuffNode( DWORD dwDataLen );

 BOOL AddBuffNode( char* pBuf, DWORD dwLenType );

 // 根据传入的数据长度,确定相关的内存池
 BUFFER_LENGTH_TYPE   GetBufLenType( DWORD dwDataLen );
};

#endif

MemoryManager.cpp

#include "MemoryManager.h"
#include <assert.h>

class CMemoryManagerBadInit
{
public:
 CMemoryManagerBadInit() {}
};

CMemoryManager::CMemoryManager( VOID )
{
 m_pMemoryPool_32 = NULL;
 m_pMemoryPool_64 = NULL;
 m_pMemoryPool_128 = NULL;
 m_pMemoryPool_256 = NULL;
 m_pMemoryPool_512 = NULL;
 m_pMemoryPool_1024 = NULL;
 m_pMemoryPool_2048 = NULL;
 m_pMemoryPool_4096 = NULL;

 AllocBuffer();

}

CMemoryManager::~CMemoryManager( VOID )
{  
 FreeBuffer();
}

VOID CMemoryManager::AllocBuffer( VOID )

 //1000000;  // 32M
 m_pMemoryPool_32 = new CMemoryPool( 10000, 32 );
 if ( NULL == m_pMemoryPool_32 )
 {
  throw CMemoryManagerBadInit();
 }

 //1000000;  // 61M
 m_pMemoryPool_64 = new CMemoryPool( 10000, 64 );
 if ( NULL == m_pMemoryPool_64 )
 {
  throw CMemoryManagerBadInit();
 }

 //1000000; // 122M
 m_pMemoryPool_128 = new CMemoryPool( 10000, 128 );
 if ( NULL == m_pMemoryPool_128 )
 {
  throw CMemoryManagerBadInit();
 }

 //500000;  // 122M  
 m_pMemoryPool_256 = new CMemoryPool( 10000, 256 );
 if ( NULL == m_pMemoryPool_256 )
 {
  throw CMemoryManagerBadInit();
 }

 //500000;  // 244M 
 m_pMemoryPool_512 = new CMemoryPool( 10000, 512 );
 if ( NULL == m_pMemoryPool_512 )
 {
  throw CMemoryManagerBadInit();
 }

 //30000; // 29M 
 m_pMemoryPool_1024 = new CMemoryPool( 10000, 1024 );
 if ( NULL == m_pMemoryPool_1024 )
 {
  throw CMemoryManagerBadInit();
 }

 //30000;  // 58M 
 m_pMemoryPool_2048 = new CMemoryPool( 10000, 2048 );
 if ( NULL == m_pMemoryPool_2048 )
 {
  throw CMemoryManagerBadInit();
 }

 //30000;  // 116M
 m_pMemoryPool_4096 = new CMemoryPool( 10000, 4096 );
 if ( NULL == m_pMemoryPool_4096 )
 {
  throw CMemoryManagerBadInit();
 }
}

VOID CMemoryManager::FreeBuffer( VOID )
{
 if ( NULL == m_pMemoryPool_32 )
 {
  delete m_pMemoryPool_32;
  m_pMemoryPool_32 = NULL;
 }

 if ( NULL == m_pMemoryPool_64 )
 {
  delete m_pMemoryPool_64;
  m_pMemoryPool_64 = NULL;
 }

 if ( NULL == m_pMemoryPool_128 )
 {
  delete m_pMemoryPool_128;
  m_pMemoryPool_128 = NULL;
 }

 if ( NULL == m_pMemoryPool_256 )
 {
  delete m_pMemoryPool_256;
  m_pMemoryPool_256 = NULL;
 }

 if ( NULL == m_pMemoryPool_512 )
 {
  delete m_pMemoryPool_512;
  m_pMemoryPool_512 = NULL;
 }

 if ( NULL == m_pMemoryPool_1024 )
 {
  delete m_pMemoryPool_1024;
  m_pMemoryPool_1024 = NULL;
 }

 if ( NULL == m_pMemoryPool_2048 )
 {
  delete m_pMemoryPool_2048;
  m_pMemoryPool_2048 = NULL;
 }

 if ( NULL == m_pMemoryPool_4096 )
 {
  delete m_pMemoryPool_4096;
  m_pMemoryPool_4096 = NULL;
 }

}

char* CMemoryManager::GetBuffNode( DWORD dwDataLen )
{
 DWORD dwType = ( DWORD )GetBufLenType( dwDataLen );

 char *p = NULL;
 
 p = GetBuffer( dwType );

 return p;
}

BUFFER_LENGTH_TYPE CMemoryManager::GetBufLenType( DWORD dwDataLen )
{
 if ( 4096 < dwDataLen )
 {
  return DATA_LENGTH_ERROR;
 }

 if ( dwDataLen <= 32 )
 {
  return DATA_LENGTH_32;
 }

 if ( ( dwDataLen > 32 ) && ( dwDataLen <= 64 ) ) 
 {
  return DATA_LENGTH_64;
 }

 if ( ( dwDataLen > 64 ) && ( dwDataLen <= 128 ) )
 {
  return DATA_LENGTH_128;
 }

 if ( ( dwDataLen > 128 ) && ( dwDataLen <= 256 ) )
 {
  return DATA_LENGTH_256;
 }

 if ( ( dwDataLen > 256 ) && ( dwDataLen <= 512 ) )
 {
  return DATA_LENGTH_512;
 }

 if ( ( dwDataLen > 512 ) && ( dwDataLen <= 1024 ) )
 {
  return DATA_LENGTH_1024;
 }

 if ( ( dwDataLen > 1024 ) && ( dwDataLen <= 2048 ) )
 {
  return DATA_LENGTH_2048;
 }

 if ( ( dwDataLen > 2048 ) && ( dwDataLen <= 4096 ) )
 {
  return DATA_LENGTH_4096;
 }

 return DATA_LENGTH_ERROR;
}

char* CMemoryManager::GetBuffer( DWORD dwType )
{
 char* p = NULL;

 switch ( dwType )
 {
  
 case ( DWORD )DATA_LENGTH_32:
  {
   p = m_pMemoryPool_32->GetBufferNode();
  }
  break;

 case ( DWORD )DATA_LENGTH_64:
  {
   p = m_pMemoryPool_64->GetBufferNode();
  }
  break;

 case ( DWORD )DATA_LENGTH_128:
  {
   p = m_pMemoryPool_128->GetBufferNode();
  }
  break;

 case ( DWORD )DATA_LENGTH_256:
  {
   p = m_pMemoryPool_256->GetBufferNode();
  }
  break;

 case ( DWORD )DATA_LENGTH_512:
  {
   p = m_pMemoryPool_512->GetBufferNode();
  }
  break;

 case ( DWORD )DATA_LENGTH_1024:
  {
   p = m_pMemoryPool_1024->GetBufferNode();
  }
  break;

 case ( DWORD )DATA_LENGTH_2048:
  {
   p = m_pMemoryPool_2048->GetBufferNode();
  }
  break;

 case ( DWORD )DATA_LENGTH_4096:
  {
   p = m_pMemoryPool_4096->GetBufferNode();
  }
  break;

 case ( DWORD )DATA_LENGTH_ERROR:
  break;

 default:
  break;
 }

 return p;
}

BOOL CMemoryManager::AddBuffNode( char* pBuf, DWORD dwLenType )
{
 if ( NULL == pBuf )
 {
  return FALSE;
 }

 BOOL b = TRUE;
 
 switch ( dwLenType )
 {

 case ( DWORD )DATA_LENGTH_32:
  {   
   m_pMemoryPool_32->AddBufferNode( pBuf );
  }
  break;

 case ( DWORD )DATA_LENGTH_64:
  {
   m_pMemoryPool_64->AddBufferNode( pBuf );
  }
  break;

 case ( DWORD )DATA_LENGTH_128:
  {
   m_pMemoryPool_128->AddBufferNode( pBuf );
  }
  break;

 case ( DWORD )DATA_LENGTH_256:
  {
   m_pMemoryPool_256->AddBufferNode( pBuf );
  }
  break;

 case ( DWORD )DATA_LENGTH_512:
  {
   m_pMemoryPool_512->AddBufferNode( pBuf );
  }
  break;

 case ( DWORD )DATA_LENGTH_1024:
  {
   m_pMemoryPool_1024->AddBufferNode( pBuf );
  }
  break;

 case ( DWORD )DATA_LENGTH_2048:
  {
   m_pMemoryPool_2048->AddBufferNode( pBuf );
  }
  break;

 case ( DWORD )DATA_LENGTH_4096:
  {
   m_pMemoryPool_4096->AddBufferNode( pBuf );
  }
  break;

 case ( DWORD )DATA_LENGTH_ERROR:
  {
   b = FALSE;
  }
  break;

 default:
  {
   b = FALSE;
  }
  break;
 }

 return b;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值