常见C++内存池技术

(1) 最简单的固定大小缓冲池

    适用于频繁分配和释放固定大小对象的情况, 关于这个内存池,我这里总结过: 一个高效的内存池实现


(2) dlmalloc
      应该来说相当优秀的内存池, 支持大对象和小对象,并且已被广泛使用。到这里下载: ftp://g.oswego.edu/pub/misc/malloc.c
      关于dlmalloc的 内部原理和使用资料可以参考: 内存分配器dlmalloc 2.8.3源码浅析.doc


(3) SGI STL 中的内存分配器( allocator )

 SGI STL 的 allocator 应该是目前设计最优秀的 C++ 内存分配器之一了,它的运作原理候捷老师在《 STL 源码剖析》里讲解得非常清楚。基本思路是设计一个 free_list[16] 数组,负责管理从 8 bytes 到 128 bytes 不同大小的内存块( chunk ),每一个内存块都由连续的固定大小( fixed size block )的很多 chunk 组成,并用指针链表串接起来。比如说

    free_list[3]->start_notuse->next_notuse->next_notuse->...->end_notuse;

 当用户要获取此大小的内存时,就在 free_list 的链表找一个最近的 free chunk 回传给用户,同时将此 chunk 从 free_list 里删除,即把此 chunk 前后 chunk 指针链结起来。用户使用完释放的时候,则把此chunk 放回到 free_list 中,应该是放到最前面的 start_free 的位置。这样经过若干次 allocator 和 deallocator 后, free_list 中的链表可能并不像初始的时候那么是 chunk 按内存分布位置依次链接的。假如free_list 中不够时, allocator 会自动再分配一块新的较大的内存区块来加入到 free_list 链表中。

 可以自动管理多种不同大小内存块并可以自动增长的内存池,这是 SGI STL 分配器设计的特点。



(4) Loki 中的小对象分配器( small object allocator )

     Loki  的分配器与   SGI STL  的原理类似,不同之处是它管理   free_list  不是固定大小的数组,而是用一个   vector   来实现,因此可以用户指定   fixed size block   的大小,不像   SGI STL  是固定最大   128 bytes   的。另外它管理   free chunks   的方式也不太一样,   Loki  是由一列记录了   free block   位置等信息的   Chunk   类的链表来维护的,   free blocks   则是分布在另外一个连续的大内存区间中。而且   free Chunks  也可以根据使用情况自动增长和减少合适的数目,避免内存分配得过多或者过少。



(5)  Boost 的 object_pool

     Boost   中的   object_pool   也是一个可以根据用户具体应用类的大小来分配内存块的,也是通过维护一个   free nodes   的链表来管理的。可以自动增加   nodes   块,初始是   32    nodes   ,每次增加都以两倍数向   system heap   要内存块。   object_pool   管理的内存块需要在其对象销毁的时候才返还给   system heap  



(6)ACE 中的 ACE_Cached_Allocator 和  ACE_Free_List

  ACE 框架中也有一个可以维护固定大小的内存块的分配器,原理与上面讲的内存池都差不多。它是通过在 ACE_Cached_Allocator 中定义个 Free_list 链表来管理一个连续的大内存块的,里面包含很多小的固定大小的未使用的区块( free chunk ),同时还使用 ACE_unbounded_Set 维护一个已使用的 chuncks ,管理方式与上面讲的内存池类似。也可以指定 chunks 的数目,也可以自动增长,定义大致如下所示:

 

template< class T>
class ACE_Cached_Allocator :  public ACE_New_Allocator<T> {
public:
     //  Create a cached memory pool with @a n_chunks chunks
    
//  each with sizeof (TYPE) size.
    ACE_Cached_Allocator(SIZET n_chunks = ACE_DEFAULT_INIT_CHUNKS);
    T* allocate();
     void deallocate(T* p);
private:
     //  List of memory that we have allocated.
    Fast_Unbounded_Set< char *> _allocated_chunks;
     //  Maintain a cached memory free list.
    ACE_Cached_Free_List<ACE_Cached_Mem_Pool_Node<T> > _free_list;
};




(7)TCMalloc

  Google的开源项目gperftools, 主页在这里:https://code.google.com/p/gperftools/,该内存池也被大家广泛好评,并且在google的各种开源项目中被使用, 比如webkit就用到了它。


你可能感兴趣的:(常见C++内存池技术)