當std::vector
是類的字段時,我們遇到了一些內存問題。我們在這個向量中填充了大量的數據,這些數據在程序的某個點需要發佈。但是,即使向量容量爲零,內存也不會釋放或完全釋放。當在用戶定義的類中清空std :: vector時釋放內存
在這裏,您有我們程序的簡化版本。如您所見,類Foo
只有一個字段:a std::vector<int>
。如果我們創建一個std::vector<Foo>
並填充Foo
對象,那麼當我們清空每個對象內部的矢量時,內存不會完全釋放。
我們使用活動監視器測量了內存使用情況,您可以在每個日誌行旁邊看到每個階段中使用的字節數。此外,我們增加了另一個版本,我們不使用類Foo
對象,在這種情況下,內存被完美釋放。
#include <iostream>
#include <vector>
class Foo {
public:
std::vector<int> container;
};
int main() {
int n1 = 1000;
int n2 = 100000;
{
std::vector<Foo> foos;
std::cerr << "starting" << std::endl; // 160 KiB
std::cin.get();
for (int i = 0; i < n1; i++){
Foo foo;
foo.container.assign(n2, 666);
foos.push_back(foo);
}
std::cerr << "foos filled" << std::endl; // 382.1 MiB
std::cin.get();
for (unsigned int i = 0; i < foos.size(); i++){
std::vector<int>().swap(foos[i].container);
}
std::cerr << "foos emptied" << std::endl; // 195.7 MiB
std::cin.get();
}
std::cerr << "foos destroyed?" << std::endl; // 296 KiB
std::cin.get();
{
std::vector<std::vector<int> > foos;
std::cerr << "starting" << std::endl; // 296 KiB
std::cin.get();
{
std::vector<int> aux;
aux.assign(n2, 666);
foos.assign(n1, aux);
}
std::cerr << "foos filled" << std::endl; // 382.1 MiB
std::cin.get();
for (unsigned int i = 0; i < foos.size(); ++i) {
std::vector<int>().swap(foos[i]);
}
std::cerr << "foos emptied" << std::endl; // 708 KiB
std::cin.get();
}
std::cerr << "foos destroyed?" << std::endl; // 708 KiB
std::cin.get();
return 0;
}
如果有幫助,我們在Ubuntu 14.04 64位下使用g ++ 4.8.4。具體的內存佔用率取決於我們使用C++ 11還是C++ 98,但在兩種情況下都會出現相同的現象。
關於發生了什麼以及如何恢復該內存的任何想法,如果需要強制執行?
編輯:請注意,當我們銷燬Foo
類的所有對象時,內存大部分會返回,但在我們現實世界的問題中,我們仍然需要Foo
-analogue類的其餘內容。
你是怎麼測量的?如果內存在內部被釋放,通常任何由OS進程獲得的內存都不會「返回」。 –
恐怕是生活的一部分。但它確實會造成問題嗎?現代操作系統和C++運行時在需要時可以釋放內存。 – Bathsheba
釋放應用程序中的內存不需要將所有內存釋放回操作系統,因爲操作系統級別的分配可能更大。 – drescherjm