2010-04-13 222 views
9

我正在使用std :: map,並且我似乎無法將內存釋放回操作系統。它看起來像,如何強制我的std :: map釋放使用的內存?

int main(){ 
    aMap m; 

    while(keepGoing){ 
    while(fillUpMap){ 
     //populate m 
    } 
    doWhatIwantWithMap(m); 
    m.clear();//doesnt free memory back to OS 

    //flush some buffered values into map for next iteration 
    flushIntoMap(m); 
    } 
} 

每個(fillUpmap)分配各地1GIG,所以我在它吃了我所有的記憶之前得到這回我的系統非常感興趣。

我經歷了與std :: vector相同,但在那裏我可以強制它通過與空的std :: vector進行交換來釋放它。這不適用於地圖。

當我使用valgrind時,它說所有的內存都被釋放,所以它不是泄漏問題,因爲一切運行後都會很好​​地清理掉。

編輯:

清除後必須出現刷新。

+1

請注意,當您嘗試分配內存時,您的操作系統可能會分配地址空間,但只有在您觸摸內存時分配實際的物理內存。如果您不再使用該RAM,但其他​​程序需要它,則其內容將被換出到磁盤。結果釋放內存實際上釋放了內存。 – MSalters 2010-04-13 11:39:23

回答

0

如果您在堆上創建地圖(通過新建),刪除它將釋放它使用的所有內存。

3

這種行爲是正常的,運行時庫保持由映射類分配的內存可用於進程,以便下一次需要分配內存時它不必進入操作系統。這是一個運行時庫優化。

13

m.clear()將內存釋放回堆中,但是堆實現通常不會將其釋放回操作系統(即使它們可以,例如碎片等問題使其變得很難)。

這是默認分配器的工作方式,如果您爲映射指定了自己的分配器,則它可能有自己的緩存。然而,即使在這種情況下,它也應該被緩存以便立即被重用。

地圖沒有容量的大小和矢量的大小的概念。

0

也許你可以創建一個自定義分配器,或者只使用Boost's池庫。

1

當我將一些數據放入std :: map然後調用std :: map :: clear()時,我做了一個簡單的測試。

typedef std::map<int, unit_t,std::less<int>, 
    my_allocator<std::pair<const int, unit_t>, 4 > > contaner_t; 
contaner_t keys; 
keys[1] = 10; 
keys[2] = 20; 
keys[3] = 30; 
keys.clear(); 

這是printf的插在我的測試結果:

Allocator # 4, Memory consumption:  56  (allocated :  56) 
Allocator # 4, Memory consumption:  112  (allocated :  56) 
Allocator # 4, Memory consumption:  168  (allocated :  56) 
Allocator # 4, Memory consumption:  112  (deallocated :  56), 
Allocator # 4, Memory consumption:  56  (deallocated :  56), 
Allocator # 4, Memory consumption:  0  (deallocated :  56), 

我想你也許還應該檢查你的分配行爲,但我認爲你默認的std ::分配器實際上釋放內存爲你期望但內存不會返回到操作系統。順便說一下你用什麼操作系統?

這裏的問題是你如何衡量can't seem to free the memory back to the OS.,你怎麼能確定I could force it to free by doing a swap with an empty std::vector.你真的確定分配的內存實際上回到操作系統?

0

Swap Trick?我知道你就是這樣用矢量和類似的方法做的,但是我之前用地圖做過。