2010-06-01 72 views
3

假設我需要經常(任意大小)分配和刪除堆上的對象,如果不是刪除這些對象,而是將它返回給某個「池」以便稍後重用,是否有任何性能優勢?回收釋放對象

它會減少堆分配/釋放嗎?或者它會比內存分配器性能更慢,因爲「池」需要管理動態指針集合。我的用例:假設我創建了一個基於鏈表的隊列容器,並且該表中的每個節點都分配在堆上,所以每次調用push()和pop()將分配和釋放該節點:

`

template <typename T> struct QueueNode { 
    QueueNode<T>* next; 
    T object; 
} 

template <typename T> class Queue { 
    void push(T object) { 
     QueueNode<T>* newNode = QueueNodePool<T>::get(); //get recycled node 
     if(!newNode) { 
      newNode = new QueueNode<T>(object); 
     } 
     // push newNode routine here.. 
    } 
    T pop() { 
     //pop routine here... 
     QueueNodePool<T>::store(unusedNode); //recycle node 
     return unusedNode->object; 
    } 
} 

`

+0

我的另一個問題是想我需要使用隊列或列表,然後每次來管理回收點你調用push(),你實際上在池中做了pop(),並且push()來排隊,這將會是更長的兩倍,是明智的嗎? – uray 2010-06-01 21:48:23

回答

1

我有類似的擔憂,當我問this question.的答案可能是有見地的你,特別是那些解決內存碎片的關注。

0

這是一個特別有用的工具,使內存分配更具確定性。如果預先分配了從中生成池的大塊,它還可以減少內存碎片。

0

根據您的運行時庫,您可能在很多情況下具有「足夠好」的分配器。也就是說,如果你能證明你有一個特殊的用例,或者libc中malloc的實現不好,你應該只爲你的應用程序構建一個池分配器。

由於Doug Lea的大部分工作都存在於GNU庫中,因此您可能想了解他在A Memory Allocator中的經驗。

+0

我上次檢查時,glibc自帶的默認分配器已經爲小對象實現了空閒列表(又名池)(如果我沒有記錯的話,最多可以有16個字節,或者是64嗎?)。 – 2010-06-01 22:12:10

+0

@Emile,多謝了一點信息。我猜自定義池的最大理由是*不知道您的目標客戶將使用哪種libc。 – 2010-06-01 22:15:19