標籤:

為什麼調用 std::map::clear() 後內存佔用率沒有降低?

size很大的一個map,用完後調用了clear()函數,按說內存使用率應該能降低很多,top命令觀察,結果是內存使用率沒有降低,為什麼呢?

求解答,謝謝。


只有含 reserve()/capacity() 成員函數的容器才需要用 swap idiom 來釋放空間,而 C++ 里只有 vector 和 string 這兩個符合條件。在 C++11 中可以直接使用 shrink_to_fit()。

list/deque/set/map 等容器是沒有 reserve() 和 capacity() 這兩個成員函數的,因此 swap 是無用功(除非用戶代碼使用了定製的 per-object allocator)。


現在的人都是根本不明白什麼是依賴介面編程。介面就是規範。STL的標準文檔並沒有規定容器的內存是怎麼用的。人家只規定,某一個調用序列最後會出現什麼結果。所有的結果都是跟輸入和輸出有關,而不是跟內部狀態有關係的。為什麼你們可以問出這種問題呢?太可怕了。


C++ 的默認 allocator 使用內存池,map::clear 只是將內存還給池子,池子里的內存不會還給操作系統,但可以被 allocator 復用


clear() 確保 map 中每個 item 的 destructor 都被調用,然後 map 在邏輯上為空。後續的添加 item 等同於在空 map 上添加 item 。

但是 clear() 並不確保一定釋放內存。釋放內存用 map::swap 和一個空 map 交換。

另外,釋放回 heap 的內存並不一定馬上交還給 OS 。Top 不能查看 heap 的內存分配,只能查看 process 本身的內存 footprint 。


直接上代碼,來自chromium:

[chrome] Contents of /trunk/src/base/stl_util.h

// Clears internal memory of an STL object.
// STL clear()/reserve(0) does not always free internal memory allocated
// This function uses swap/destructor to ensure the internal memory is freed.
template&
void STLClearObject(T* obj) {
T tmp;
tmp.swap(*obj);
// Sometimes "T tmp" allocates objects with memory (arena implementation?).
// Hence using additional reserve(0) even if it doesn"t always work.
obj-&>reserve(0);
}


一般的STL底層都有設計一個叫做memory pool的東東.它用於管理小片段內存並做次級內存分配,你掉用clear的時候內存會交還給memory pool而不會真正釋放. 請參考allocator的設計.


clear只是清除了標記,或者設置標記,表示它被刪除了,其實沒有刪除,如果要刪除全部可以交換一個空MAP和當前MAP內容。


什麼時候stl中的map也需要swap才能釋放內存?只有vector才需要swap交換釋放內存,map本來就是這麼設計的,顯示的invoke clear之後並未立即將佔用內存還給OS的。


STL源碼剖析讀書筆記


樓上有些回答感覺互相矛盾的,既然allocator釋放內存是返回給池子,那麼用swap方式釋放內存效果也應該是一樣的。。。stl裡面的代碼看著像坨屎,我從來沒有看過.

=

現在感覺stl還可以吧


正好做過這個,因為這個問題專門看來glibc源碼 建議用malloc_trim(0),就可以了

其實malloc下面存在分配區 top chunk等概念,類似於內存池


推薦閱讀:

最近電腦每次開機內存佔用與上次關機時差不多,只有重啟後內存才會降到20左右,這是怎麼回事啊?
電腦內存突然佔用過多是為什麼?
如何理解 Objective-C 中的 strong 和 weak ?
CPU到底是怎麼操作獨立顯卡的?
為什麼 intrusive_ptr 沒有進入標準庫?

TAG:內存管理 | STL | C |