实现自己的内存池

打开浏览器,搜索了下内存管理的概念,百度百科中是这样定义的:内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。说到内存,与之紧密相联系的一个概念就是指针。回想起上学那会儿,自己对指针是即喜欢,又害怕。因为学好了指针,就可以学好C,继而学好C++,但面对那些晦涩的概念,和程序运行中一些莫名其妙的指针越界、内存泄露……,不免叫人步步惊心。后来参加工作了,在不断的摸爬滚打中,也逐渐对指针和内存熟悉起来。

    在编写网络通信程序时,要用到自己的发送缓冲区或接收缓冲区,其实这些缓冲区,都是一块特定的内存。特别在编写服务端程序时,能否管理好自己的内存,对于程序的灵活,高效,稳定,起到莫大的作用。再看一下内存管理的定义,它说的是在PC上,现实中也有很多程序不在PC上,比如基于Linux系统的嵌入式设备。其内存一般也就几M,几十M的样子。在编写设备通信程序,比如协议栈时,就更应该管理好自己的内存啦!

    下边,我参考开源项目POCO C++ Libraries,用C++编写了一个内存池类,也算是对学习和工作的一个总结,同时方便今后使用。代码中使用了线程互斥锁,这个可以在互斥对象锁和临界区锁性能比较(Win32)和Linux平台上用C++实现多线程互斥锁看到。以下代码已在VS2005环境下编译通过。

 

MemPool.h

#ifndef _MEM_POOL_H  
  1. #define _MEM_POOL_H  
  2.   
  3. #include <vector>  
  4. #include <iostream>  
  5. #include "Lock.h"  
  6.   
  7. using namespace std;  
  8.   
  9. /* 
  10.     在内存池中分配固定大小的内存块 
  11.  
  12.     该类的目的是加速内存分配速度,并且减少因重复分配相同 
  13.     内存时产生的内存碎片,比如在服务器应用程序中。 
  14. */  
  15.   
  16. class CMemPool  
  17. {  
  18. public:  
  19.   
  20.     //创建大小为blockSize的内存块,内存池数目为预分配的数目preAlloc  
  21.     CMemPool(std::size_t blockSize, int preAlloc = 0, int maxAlloc = 0);  
  22.   
  23.     ~CMemPool();  
  24.   
  25.     //获取一个内存块。如果内存池中没有足够的内存块,则会自动分配新的内存块  
  26.     //如果分配的内存块数目达到了最大值,则会返回一个异常  
  27.     void* Get();  
  28.   
  29.     //释放当前内存块,将其插入内存池  
  30.     void Release(void* ptr);  
  31.   
  32.     //返回内存块大小  
  33.     std::size_t BlockSize() const;  
  34.   
  35.     //返回内存池中内存块数目  
  36.     int Allocated() const;  
  37.   
  38.     //返回内存池中可用的内存块数目  
  39.     int Available() const;  
  40.   
  41. private:  
  42.     CMemPool();  
  43.     CMemPool(const CMemPool&);  
  44.     CMemPool& operator = (const CMemPool&);  
  45.   
  46.     enum  
  47.     {  
  48.         BLOCK_RESERVE = 32  
  49.     };  
  50.   
  51.     typedef std::vector<char*> BlockVec;  
  52.   
  53.     std::size_t m_blockSize;  
  54.     int         m_maxAlloc;  
  55.     int         m_allocated;  
  56.     BlockVec    m_blocks;  
  57.     CMutex      m_mutex;  
  58. };  
  59.   
  60. inline std::size_t CMemPool::BlockSize() const  
  61. {  
  62.     return m_blockSize;  
  63. }  
  64.   
  65.   
  66. inline int CMemPool::Allocated() const  
  67. {  
  68.     return m_allocated;  
  69. }  
  70.   
  71.   
  72. inline int CMemPool::Available() const  
  73. {  
  74.     return (int) m_blocks.size();  
  75. }  
  76.   
  77.   
  78. #endif  

 

MemPool.cpp

#include "MemPool.h"  
  1.   
  2. CMemPool::CMemPool(std::size_t blockSize, int preAlloc, int maxAlloc):  
  3. m_blockSize(blockSize),  
  4. m_maxAlloc(maxAlloc),  
  5. m_allocated(preAlloc)  
  6. {  
  7.     if ( preAlloc < 0 || maxAlloc == 0 || maxAlloc < preAlloc )  
  8.     {  
  9.         cout<<"CMemPool::CMemPool parameter error."<<endl;  
  10.     }  
  11.   
  12.     int r = BLOCK_RESERVE;  
  13.     if (preAlloc > r)  
  14.         r = preAlloc;  
  15.     if (maxAlloc > 0 && maxAlloc < r)  
  16.         r = maxAlloc;  
  17.     m_blocks.reserve(r);  
  18.     for (int i = 0; i < preAlloc; ++i)  
  19.     {  
  20.         m_blocks.push_back(new char[m_blockSize]);  
  21.     }  
  22. }  
  23.   
  24.   
  25. CMemPool::~CMemPool()  
  26. {  
  27.     for (BlockVec::iterator it = m_blocks.begin(); it != m_blocks.end(); ++it)  
  28.     {  
  29.         delete [] *it;  
  30.     }  
  31. }  
  32.   
  33.   
  34. void* CMemPool::Get()  
  35. {  
  36.     CLock lock(m_mutex);  
  37.   
  38.     if (m_blocks.empty())  
  39.     {  
  40.         if (m_maxAlloc == 0 || m_allocated < m_maxAlloc)  
  41.         {  
  42.             ++m_allocated;  
  43.             return new char[m_blockSize];  
  44.         }  
  45.         else  
  46.         {  
  47.             cout<<"CMemPool::get CMemPool exhausted."<<endl;  
  48.             return (void *)NULL;  
  49.         }  
  50.     }  
  51.     else  
  52.     {  
  53.         char* ptr = m_blocks.back();  
  54.         m_blocks.pop_back();  
  55.         return ptr;  
  56.     }  
  57. }  
  58.   
  59.   
  60. void CMemPool::Release(void* ptr)  
  61. {  
  62.     CLock lock(m_mutex);  
  63.   
  64.     m_blocks.push_back(reinterpret_cast<char*>(ptr));  
  65. }  

 

    下边是测试代码

// CMyMemPool.cpp : 定义控制台应用程序的入口点。  
  1. //  
  2.   
  3. #include "stdafx.h"  
  4. #include "MemPool.h"  
  5.   
  6. #define DATA_BLOCK_LEN 1500  
  7.   
  8. int _tmain(int argc, _TCHAR* argv[])  
  9. {  
  10.     CMemPool myPool1(DATA_BLOCK_LEN, 0, 10);  
  11.   
  12.     cout<<"myPool1 block size = "<<myPool1.BlockSize()<<endl;  
  13.     cout<<"myPool1 allocated block num = "<<myPool1.Allocated()<<endl;  
  14.     cout<<"myPool1 available block num = "<<myPool1.Available()<<endl<<endl;  
  15.   
  16.     std::vector<void*> ptrs;  
  17.     for (int i = 0; i < 10; ++i)  
  18.     {  
  19.         ptrs.push_back(myPool1.Get());  
  20.     }  
  21.   
  22.     myPool1.Get();  
  23.   
  24.     int iavilable = 0;  
  25.     for (std::vector<void*>::iterator it = ptrs.begin(); it != ptrs.end(); ++it)  
  26.     {  
  27.         myPool1.Release(*it);  
  28.         ++iavilable;  
  29.         cout<<"myPool1 available block num = "<<myPool1.Available()<<endl;  
  30.     }  
  31.   
  32.     CMemPool myPool2(DATA_BLOCK_LEN, 5, 10);  
  33.     cout<<endl<<"myPool2 block size = "<<myPool2.BlockSize()<<endl;  
  34.     cout<<"myPool2 allocated block num = "<<myPool2.Allocated()<<endl;  
  35.     cout<<"myPool2 available block num = "<<myPool2.Available()<<endl;  
  36.   
  37.     int iWait;  
  38.     cin>>iWait;  
  39.   
  40.     return 0;  
  41. }  


    编译,运行

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值