首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

最容易的内存池-原理与实现

2012-10-31 
最简单的内存池-原理与实现??? 内存池的主要作用,简单地说来,便是提高内存的使用效率。堆内存的申请与释放(

最简单的内存池-原理与实现

??? 内存池的主要作用,简单地说来,便是提高内存的使用效率。堆内存的申请与释放(new/delete及malloc/free),涉及复杂的内存分配算法, 相比由简单CPU指令支持的栈内存的申请与释放,则是慢上了数量级。另一方面,栈的大小是有限制的,在需要大量内存的操作时,堆的使用是必要的。当然,频繁地申请与释放堆内存,效率是很低的,这也就是内存池出现的原因。
??? 类似std::vector容器,在向vector里添加一个元素之前,该容器往往提前申请了一大块内存,实际添加时就只需要拿出其中一小块来使用,不用每添加一个都使用new一次。内存池所做的,也就是一次申请一块大内存,然后再小块小块地拿出来用:一次申请NM大小的内存,必然比N次申请M大小的内存要快,这就是内存池高效的简单解释。
??? 一般来说,内存池可以按两种维度划分:单线程与多线程,可变大小和固定大小。其中最简单的单线程固定大小的内存池。这类内存池只考虑单线程的程序,分配与回收的对象都是固定大小的。这个简单的内存池类模板声明如下:


?
??? 当用户向内存池申请一个对象T时,内存池会检查freeChunk是否为NULL。不为NULL时,表示还有自由的小内存块(ObjectChunk)可供使用,将它返回给用户,并将freeChunk移到下一个自由内存块;若freeChunk为NULL,则内存池需要使用 new/malloc从申请一块大内存(MemBlock),然后将其中的BaseSize个ObjectChunk都串连上形成链表,再将 freeChunk做为头指针。这时freeChunk不为NULL了,可以提供给用户一块小内存了(具体即是,取出链表的首结点)。

template<typename T, int BaseSize=32>class SimpleMemPool{private:#pragma pack(push, 1)   union ObjectChunk   {       ObjectChunk * next;       char buf[ sizeof(T)];   };    struct MemBlock   {       MemBlock* next;       ObjectChunk chunks[BaseSize];   };#pragma pack(pop)   SimpleMemPool(const SimpleMemPool<T, BaseSize> &) { }      MemBlock * head;     ObjectChunk * freeChunk;public:     SimpleMemPool() : head(0), freeChunk(0)     {       }     ~SimpleMemPool()     {           while(head)         {             MemBlock * t = head;             head = head->next;             delete t;         }     }     T* New()     {         if (!freeChunk)         {             MemBlock * t = new MemBlock;             t->next = head;             head = t;             for(unsigned int i=0; i<BaseSize-1;++i)             {                 head->chunks[i].next = & (head->chunks[i+1]);             }             head->chunks[BaseSize-1].next = 0;             freeChunk = & (head->chunks[0]);         }         ObjectChunk * t = freeChunk;         freeChunk = freeChunk->next;         return reinterpret_cast<T*>(t);     }     void Delete(T* t)     {         ObjectChunk * chunk = reinterpret_cast<ObjectChunk*>(t);         chunk->next= freeChunk;         freeChunk = chunk;     }};

?

热点排行