0

我使用unordered_map Solaris 10上使用克++ 4.9.2堆,但令人驚訝的我發現清晰()不釋放堆。 這裏的示例代碼:unordered_map:清除()不釋放在明確()

#include <iostream> 
#include <unordered_map> 

int main() 
{ 
    std::unordered_map<long long, long long> mymap; 
    mymap.rehash(200000); 
    getchar(); 
    for (int i = 0; i < 2000000; i++) { 
    mymap[i] = i*i; 
    } 
    std::cout << "current bucket_count: " << mymap.bucket_count() << std::endl; 
    std::cout << "current size: " << mymap.size() << std::endl; 
    getchar(); 
    mymap.clear(); 
    std::cout << "current bucket_count: " << mymap.bucket_count() << std::endl; 
    std::cout << "current size: " << mymap.size() << std::endl; 
    getchar(); 
    return 0; 
} 

我觀察堆大小的程序時progranm上的getchar等待()。而且,這裏的德堆快照通過pmap -x <PID> | grep heap

1. While waiting on 1st getchar(): `0002C000  792  792  792  - rwx-- [ heap ]` 

2. After 1st getchar(): it prints: 

    current bucket_count: 3439651 
    current size: 2000000 
Heap shows while waiting on 2nd getchar(): 

    0002C000 3920 3920 3920  - rwx-- [ heap ] 
    00400000 73728 72272 72272  - rwx-- [ heap ] 

3. After 2nd getchar(): it prints: 

    current bucket_count: 3439651 
    current size: 0 
Heap shows while waiting on 2nd getchar(): 
0002C000 3920 3920 3920  - rwx-- [ heap ] 
00400000 73728 72272 72272  - rwx-- [ heap ] 

這說明發現(步驟3)明確的()對堆沒有影響。雖然,文檔說,

std::unordered_map::clear 
void clear() noexcept; 
Clear content 
All the elements in the unordered_map container are dropped: their destructors are called, and they are removed from the container, leaving it with a size of 0. 

但是,我的堆計數並不反映這一點。 是否有任何其他方式釋放unordered_map對象佔用的堆?或者,我應該使用別的東西嗎? 請指導如何從unordered_map釋放內存?

+0

您從「文檔」中引用的引用沒有說明釋放地圖內部使用的內存,只是地圖將變爲空。這顯然是(因爲你打印尺寸爲零)。 –

+3

我認爲你必須明白大小和容量是有區別的,即使它釋放了用於包含元素的內存,它也不會釋放底層的數據結構。當你調用清除它可能調用析構函數,並設置一些大小變量爲0,但不釋放容器所擁有的內存。 –

+0

從操作系統獲取內存以響應'new'調用返回時,C++運行時庫將不會釋放它,直到該過程結束。 –

回答

1

您的地圖內容被刪除。與磁盤上的文件類似(僅從索引擦除)。如果您可以在下次使用它,釋放內存將不會有效。

如果你不會真的釋放地圖內存,你需要摧毀整個對象。或者您可以嘗試撥打電話void reserve(size_type count);。 (I還沒有嘗試過)

+0

備用(0)可能不起作用,因爲它不具有約束力,且備用值將小於容量。 – Swtsvn

1

unordered_map:清除()不釋放在明確()

C++標準堆不需要clear以釋放存儲器。

但是,我的堆計數不反映這一點。

文檔隻字不提堆。元素的析構函數被調用,並且如您所確認的那樣,大小爲0.如果添加新元素,它們可能會重新使用先前清除的元素所使用的內存。

是否有任何其他方式釋放unordered_map對象佔用的堆?

銷燬地圖一定會釋放其所有內存。

mymap.rehash(0)也可能工作。

但是,僅僅因爲內存被釋放(通過調用free),並不意味着該實現必然會將內存釋放到操作系統。實現可能會決定爲其他分配重新使用內存(儘管這通常只適用於小分配)。

有在C++中做到這一點沒有標準的方式,但Linux提供了一個功能malloc_trim即會嘗試從堆到OS的頂部釋放釋放的內存。

0

的內存沒有釋放,因爲地圖被認爲是在繼續使用,直至超出範圍或已被刪除。對於這個合理的默認用例,重新分配會導致不必要的開銷。我的建議:

  • 如果確實不再需要它,將它的範圍限制在你需要它的地方,分別使用具有適當範圍的地圖的智能指針。
  • 如果你仍然需要它,但不是一段時間,或只有少得多的元素,swap它與一個空的臨時地圖(這將被刪除)。
  • 顯式調用析構函數並重新創建新地圖。