1. 程式人生 > >STL中的list/set/map等容器clear之後的記憶體佔用

STL中的list/set/map等容器clear之後的記憶體佔用

最近在知乎上看到一個問題:

為什麼呼叫 std::map::clear() 後記憶體佔用率沒有降低?

size很大的一個map,用完後呼叫了clear()函式,按說記憶體使用率應該能降低很多,top命令觀察,結果是記憶體使用率沒有降低,為什麼呢?
求解答,謝謝。

網址:http://www.zhihu.com/question/19752706

問題下面已經有很多大神給出瞭解釋。

我的理解是:std::map::clear()之後記憶體佔用會不會降低是由兩個方面決定的。

首先是容器使用的空間分配器(allocator)。所有版本的STL都給出了至少兩種可用的空間分配器:malloc_allocator和new_allocator。這兩個分配器其實分別是對malloc/free和new/delete的封裝,引入了相應的異常處理機制而已。顯然,使用了這兩種分配器的容器在clear()之後已經把記憶體還給了C的執行環境。SGI STL中設計了二級空間分配器,對於小於128B的記憶體,將從自己記憶體池中取,釋放時也只是還給記憶體池,記憶體池直到程序退出才將申請的記憶體全部還給執行環境。所以在這種情況下,對於小於128B的記憶體,clear()後記憶體佔用率不可能降低。然而實際上很多編譯器自帶的STL空間分配器都預設使用new_allocator,可能出於SGI STL二級空間分配器效率不高的考慮,至少本人實際測試過的Windows下的msvc和Ubuntu下的gcc都預設使用new_allocator。

其次是不同的C執行時庫(glibc,libcpmt,libmsvcprt等等)對於碎片的處理不同,也就是malloc/free的內部實現機制不同。對於較小的記憶體塊,free()並不直接還給作業系統,而是暫時儲存起來,以免記憶體碎片過多。http://bbs.chinaunix.net/thread-1796237-1-2.html中提到glibc中128kB的記憶體塊將被直接返回給作業系統。由此可見glibc設定的閾值還是比較大的。