1. 程式人生 > >常見C++記憶體池技術

常見C++記憶體池技術

總結下常見的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 bytes128 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的位置。這樣經過若干次allocatordeallocator後,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就用到了它。

posted on 2013-04-08 20:53 Richard Wei 閱讀(10884) 評論(0)  編輯 收藏 引用 所屬分類: C++