• 用模版实现简单的内存池


    程序中有时候会遇到这种情况,就是需要不停的去分配以及释放内存。带来的是不停的调用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 }
  • 相关阅读:
    《基于B_S模式的教务管理系统设计与实现》论文笔记(三)
    《重修补考报名考务管理信息系统中的网络技术》论文笔记(二)
    《基于WEB的独立学院补考重修管理系统研究》论文笔记(一)
    重修安排管理系统的设计与实现 文献收集
    重修安排管理系统的设计与实现 文献收集
    《暗时间》读书笔记
    R、Python、Scala 和 Java,到底该使用哪一种大数据编程语言?
    编程和音乐真的很像吗?
    关于虚拟现实叙事方式的终极入门指南
    如何避免脆弱的代码
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4950452.html
Copyright © 2020-2023  润新知