Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1779024
  • 博文数量: 198
  • 博客积分: 4088
  • 博客等级: 上校
  • 技术积分: 2391
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-15 16:29
个人简介

游戏开发,系统架构; 博客迁移到:http://www.jianshu.com/u/3ac0504b3b8c

文章分类

全部博文(198)

文章存档

2017年(1)

2016年(12)

2015年(1)

2014年(3)

2013年(13)

2012年(18)

2011年(150)

分类: C/C++

2012-01-05 18:02:42

   原理很简单,就是先开辟n个数据块,每个数据块的前四个字节next_id表示下一个可用的数据块的编号。该内存池类中有一个成员m_firstId, 表示第一个可用的数据块的编号,然后在申请内存的时候,根据这个编号,返回对应的数据块的地址。在将申请的内存块A归还给内存池时,根据其地址确定其所在的内存块编号。然后将该内存块的next_id改为m_firstId,将m_firstId改为该内存块的id。
 
Mempool.h
  1. #ifndef _MEM_POOL_H_
  2. #define _MEM_POOL_H_

  3. #include "Lock.hpp"

  4. template<class T>
  5. class Mempool
  6. {
  7. public:
  8.     struct BlockNode
  9.     {
  10.         int        next_id;
  11.         T          data;
  12.     };

  13. public:
  14.     Mempool(int nCount)
  15.         :m_nCount(nCount)
  16.         ,m_firstId(-1)
  17.         ,m_NodeHead(NULL)
  18.         ,m_pNode(NULL)
  19.     {
  20.         m_NodeHead = (BlockNode*)malloc(sizeof(BlockNode) * m_nCount);
  21.         if(m_NodeHead == NULL)
  22.         {
  23.             return;
  24.         }

  25.         memset(m_NodeHead, 0, sizeof(BlockNode) * m_nCount);

  26.         m_pNode = new BlockNode*[m_nCount];

  27.         memset(m_pNode, 0, sizeof(BlockNode*) * m_nCount);

  28.         BlockNode* temp = m_NodeHead;

  29.         for(int i = 0; i < m_nCount; ++i)
  30.         {
  31.             m_pNode[i] = temp;
  32.             temp->next_id = i + 1;
  33.             temp = (BlockNode*)((char*)temp + sizeof(BlockNode));

  34.             if(i == m_nCount - 1)
  35.             {
  36.                 temp->next_id = -1;
  37.             }
  38.         }

  39.         m_firstId = 0;
  40.     }

  41.     ~Mempool()
  42.     {
  43.         if(m_NodeHead)
  44.         {
  45.             free(m_NodeHead);
  46.             m_NodeHead = NULL;
  47.         }

  48.         if(m_pNode)
  49.         {
  50.             delete []m_pNode;
  51.             m_pNode = NULL;
  52.         }
  53.     }

  54.     inline void* mallocMemBuf()
  55.     {
  56.         AutoLock lock(&m_lock);

  57.         void* p = NULL;
  58.         if(m_firstId != -1 && m_firstId < m_nCount)
  59.         {
  60.             p = (void*)&(m_pNode[m_firstId]->data);
  61.             m_firstId = m_pNode[m_firstId]->next_id;
  62.         }
  63.         else
  64.         {
  65.             p = malloc(sizeof(T));
  66.         }

  67.         return p;
  68.     }

  69.     inline void freeMemBuf(void* pNode)
  70.     {
  71.         AutoLock lock(&m_lock);

  72.         if((pNode >= (char*)m_NodeHead) && (pNode <= (char*)m_NodeHead + sizeof(BlockNode)* m_nCount))
  73.         {
  74.             for(int i = 0; i < m_nCount; ++i)
  75.             {
  76.                 if(pNode == (void*)&(m_pNode[i]->data))
  77.                 {
  78.                     m_pNode[i]->next_id = m_firstId;
  79.                     m_firstId = i;
  80.                     return;
  81.                 }
  82.             }
  83.         }

  84.         free(pNode);
  85.     }

  86. private:
  87.     int                m_nCount;            //the block count
  88.     int                m_firstId;            //the first free block id
  89.     BlockNode*         m_NodeHead;            //the head of the list
  90.     BlockNode**        m_pNode;            //the pointer array
  91.     Lock               m_lock;    
  92. };

  93. #endif
运用实例
  1. #include <iostream>
  2. #include <time.h>
  3. #include "Mempool.hpp"

  4. using namespace std;

  5. #define _MEM_POOL_

  6. class Test
  7. {
  8. public:
  9.     Test()
  10.         :a(0)
  11.         ,b(0)
  12.     {
  13.         count1++;
  14.         //cout << "Test constructor!" << endl;
  15.     }

  16.     ~Test()
  17.     {
  18.         count2++;
  19.         //cout << "Test destructor!" << endl;
  20.     }

  21.     void setA(int _a)
  22.     {
  23.         a = _a;
  24.     }

  25.     void setB(int _b)
  26.     {
  27.         b = _b;
  28.     }

  29.     void show()
  30.     {
  31.         cout << "a = " << a << " b = " << b << endl;
  32.     }

  33. #ifdef _MEM_POOL_

  34.     inline void* operator new(unsigned int nSize )
  35.     {
  36.         if( mempool == NULL )
  37.         {
  38.             return malloc( nSize );
  39.         }
  40.         return mempool->mallocMemBuf( );
  41.     };
  42.     inline void operator delete(void* p)
  43.     {
  44.         if( mempool == NULL )
  45.         {
  46.             free( p );
  47.         }
  48.         else
  49.         {
  50.             mempool->freeMemBuf( p );
  51.         }
  52.     };

  53.     static Mempool<Test> *mempool;

  54. #endif

  55.     static int count1;
  56.     static int count2;
  57.     

  58. private:
  59.     int a;
  60.     int b;
  61.     char data[2048];
  62. };

  63. int Test::count1 = 0;
  64. int Test::count2 = 0;
  65. #ifdef _MEM_POOL_
  66. Mempool<Test>* Test::mempool = NULL;
  67. #endif

  68. int main()
  69. {
  70. #ifdef _MEM_POOL_
  71.     Test::mempool = new Mempool<Test>(5);
  72. #endif

  73.     clock_t start, end;
  74.     double duration;

  75.     start = clock();

  76.     for(int i = 0 ; i < 10000000; ++i)
  77.     {
  78.         Test *t = new Test;
  79.         //t->show();
  80.         delete t;
  81.     }

  82.     //cout << "count1 = " << Test::count1 << " count2 = " << Test::count2 << endl;

  83.     end = clock();

  84.     duration = double(end - start) / CLOCKS_PER_SEC;

  85.     cout << "total used " << duration << "s" << endl;

  86.     system("pause");

  87.     return 0;

  88. }
阅读(2440) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~