用模版实现简单的内存池

程序中有时候会遇到这种情况,就是需要不停的去分配以及释放内存。带来的是不停的调用new以及delete带来的开销。

而且由于全局的new以及delete往往对多线程做出了并发保护,所以在单线程情况下这更带来一种浪费,一般的情况下是去实现一个

单线程的内存池来进行性能优化,配合所需的类往往带来很好的性能提升。

首先是作为内存池的模板类:

 1 template<class T>
 2 class MemoryPool{
 3 public:
 4     MemoryPool(size_t size = EXPANSION_SIZE);
 5     ~MemoryPool();
 6 
 7     //从空闲列表中分配T大小的空间
 8     inline void * alloc(size_t size);
 9 
10     //释放内存到空闲列表中
11     inline void free(void * elements);
12 private:
13     MemoryPool<T> * next;   //空闲列表的下一个元素
14     enum { EXPANSION_SIZE = 32 };
15     void expandTheFreeList(int howMany = EXPANSION_SIZE);
16 };
17 
18 template<class T>
19 MemoryPool<T>::MemoryPool(size_t size)
20 {
21     expandTheFreeList(size);
22 }
23 
24 template<class T>
25 MemoryPool<T>::~MemoryPool()
26 {
27     MemoryPool<T> * nextPtr = next;
28     if (next){
29         for (nextPtr = next; nextPtr != nullptr; nextPtr = next){
30             next = next->next;
31             delete[] ((char * )nextPtr);    //这里的强制类型转换应该注意,不转换编译无法通过的当时分配
32                                             //内存的时候是按照char类型分配的,那么释放的时候也应该同样释放。
33         }
34     }
35 }
36 
37 
38 template<class T>
39 inline
40 void * MemoryPool<T>::alloc(size_t)
41 {
42     if (!next)
43         expandTheFreeList();
44     MemoryPool<T> * head = next;
45     next = head->next;//分配了一块空间
46     return head;
47 }
48 
49 template<class T>
50 inline
51 void MemoryPool<T>::free(void * doomed)
52 {
53     MemoryPool<T> * head = static_cast<MemoryPool<T> *>(doomed);
54     head->next = next;
55     next = head;
56 }
57 
58 template<class T>
59 void MemoryPool<T>::expandTheFreeList(int howMany)
60 {
61     //保证分配的内存大小至少应该是大于指针大小或者是元素大小中的 最大者,因为二者之间是共享内存的
62     size_t sizeAlloc = (sizeof(T) > sizeof(MemoryPool<T> *)) ?
63         sizeof(T) : sizeof(MemoryPool<T> *);
64     MemoryPool<T> * runner = (MemoryPool<T>*)(new char[sizeAlloc]); //这里实际上是可以使用static_cast的,但是不知道为什么,
65     next = runner;                                              //gcc下编译不能通过。可能因为gcc的限制比较严格。无奈,只能使用普通的强制类型转换
66     for (int i = 0; i < howMany; ++i){
67         runner->next = (MemoryPool<T>*)(new char[sizeAlloc]);
68         runner = runner->next;
69     }
70     runner->next = 0;
71 }

 

下面是使用该内存池的一个rational类,代码如下:

 1 class Rational{
 2 public:
 3     Rational(int a = 0, int b = 1):n(a), d(b){}
 4     void * operator new(size_t size){return memPool->alloc(size); }
 5     void operator delete(void * doomed, size_t size){memPool->free(doomed);}
 6     static void newMemPool(){memPool = new MemoryPool<Rational>; }
 7     static void deleteMemPool()
 8     {
 9         if(!memPool)
10             return;
11         delete memPool;
12     }
13 private:
14     int n;
15     int d;
16     static MemoryPool <Rational> * memPool;
17 };

使用代码如下:

 1 MemoryPool<Rational> * Rational::memPool = 0;
 2 
 3 int main()
 4 {
 5     Rational * array[10];
 6     Rational::newMemPool();
 7     for(int j = 0; j < 2; ++j){
 8         for(int i = 0; i < 10; i++){
 9             array[i] = new Rational(i);
10         }
11         for(int i = 0; i < 10; i++){
12             delete array[i];
13         }
14     }
15     Rational::deleteMemPool();
16 }

 

posted @ 2015-11-09 16:56  eversliver  阅读(523)  评论(0编辑  收藏  举报