2013-07-26 164 views
6

我遇到下面的問題,我真的不知道我是否錯誤或它的一個非常奇怪的錯誤。我填充了大量的字符串,並希望它在某個點被清除。這裏有一個小例子矢量<string>後不會清除內存,超出範圍

#include <string> 
#include <vector> 
#include <unistd.h> //sleep 
#include <iostream> 

int main(){ 
    { 
     std::vector<std::string> strvec; 
     for(long i = 0; i < 1000000; ++i){ 
      std::string out = "This is gonna be a long string just to fill up the memory used by this fucking pthread\n"; 
      strvec.push_back(out); 
     } 
     std::cout << "finished loading 1st\n"; 
     sleep(10); // to monitor any changes  
    } 
    std::cout << "out of scope\n"; 
    sleep(10); 
    return 0; 
} 

我的問題是,如果我監視與「頂」,內存使用量下降只是一個非常小的量(我認爲它可能是矢量開銷)內存使用情況,但最好像不是釋放。怎麼會?我用'long long'測試了相同的場景,但是這裏一切正常。

在std ::矢量參考狀態,即,如果所包含的值是無指針時,析構函數被調用。似乎不是真正的字符串,雖然...

我欣賞每一個答案。

(爲方便起見:我使用與克++ 4.7.2的Debian Linux的64位)

編輯:謝謝你的答案爲止。

與vagrind地塊,現在我已經異形堆的使用情況(是的,實際上是如預期)它能夠在它應該在點正確釋放。但是,爲什麼我實際上看到一個巨大的整數使用的變化,但不是與字符串(也在頂部)?

我需要對此有一定的瞭解,因爲我需要能夠在特定時間爲多線程服務器應用程序釋放我的內存,這可能會在不重啓的情況下運行數週或更長時間。我什麼時候才知道C++內存管理器決定將某些內存還給操作系統?

+0

嘗試使用[valgrind](http://valgrind.org/)進行調試,它會告訴你內存是否空閒,並且可能比'top'更有幫助。 – Couchy311

+0

什麼是人們堅持記憶被浪費?自由內存不會*沒有任何東西* - 它不比計算機中完全沒有的內存好。只有正在使用的內存纔會有好處。 –

回答

6

這是使用top命令的一個特定的,而不是在std::vector。問題是由數據結構釋放的內存不會被釋放回操作系統,這是top命令監視內存使用情況的級別。 OS給你的程序的內存一直保存在你的程序中,直到C++的內存管理器決定是時候將一些內存釋放回操作系統。

這樣做的原因是,從操作系統分配內存是比較昂貴的,它需要相對大塊做。 C++運行時庫的內存管理器從OS「批發」中獲取內存,然後根據需要將其包裝到程序的各個部分。

如果您想驗證內存是否確實被回收,請使用監視較低級別內存使用情況的工具,如valgrind

4

即使正確釋放內存,標準庫也不需要將內存釋放回操作系統。

因此,例如,當你第一次分配的所有內存,圖書館從OS(有可能與mmap(2))分配了一堆虛擬內存地址空間和多爾斯出來。但是當你完成這個內存時,它會掛起到虛擬地址空間,假設你可能會在稍後想要回存儲內存,所以它不會調用munmap(2)來取消映射虛擬地址空間。

因此,即使所有的內存已經正確地從程序的角度來看,中解脫出來,所有的OS看到的是,你分配了一堆的虛擬內存,但此後再也沒有釋放它。這就是爲什麼top(1)報告你的內存使用量沒有減少,但沒什麼可擔心的。當你的程序再次需要內存時,它會從你已經擁有的虛擬地址空間中分配它,所以你不會看到你的內存使用量增加,直到所有的內存用完。

0

正如其他答案中所述,內存仍然可用於您的進程,並且在程序退出之前不會釋放內存。如果你想要一個分配器來做到這一點,你可以使用jemalloc檢出它,它可以將它釋放回操作系統,並且對於可擴展的多線程應用程序(如Facebook)非常有用,但是與其他任何成本一樣。