我想要做的是释放vector
使用的内存(比如说vector<vector<int>>
)并使用交换技巧,即v.swap(vector<vector<int>>())
。
然而,我观察到交换技巧适用于短向量但不适用于长向量,例如我尝试了一个长度为10,000,000的向量,在内存中占用1.4G,在交换之后仍有1.0G未发布
以下是我用于测试的代码。
感谢提前任何想法!
#include <iostream>
#include <vector>
using namespace std;
typedef unsigned long long int64;
int main()
{
{
vector<vector<int64>> batch;
{
vector<int64> v;
for (size_t i = 0; i < 12; ++i)
v.push_back(8000000000);
for (size_t i = 0; i < 10000000; ++i)
batch.push_back(v);
}
cout << "pause 1" << endl;
cin.ignore();
{
vector<vector<int64>> tmp;
batch.swap(tmp);
// I tried several things here.
//tmp.swap(batch);
//batch.clear();
//batch.shrink_to_fit();
//batch = tmp;
}
cout << "pause 2" << endl;
cin.ignore();
}
cout << "pause 3" << endl;
cin.ignore();
}
答案 0 :(得分:1)
James,In silico和Max的言论都是正确的。您希望在致电batch.swap(tmp)
时释放内存,因为tmp
为空。我刚刚在64位Linux上运行你的程序,使用gcc 4.6.0编译。当用top观察内存消耗时,它会变为2 GB - > 1.8 GB - &gt; 1.8 GB。但是,添加batch2
并在pause 2
之后填充batch
就像填充batch.swap(tmp)
一样,内存消耗不会增加。运行#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
typedef unsigned long long int64;
int main(int argc, char** argv)
{
bool no_swap = (argc > 1 && strcmp(argv[1], "-noswap") == 0);
{
vector<vector<int64> > batch;
vector<vector<int64> > batch2;
{
vector<int64> v;
for (size_t i = 0; i < 12; ++i)
v.push_back(8000000000);
for (size_t i = 0; i < 10000000; ++i)
batch.push_back(v);
}
cout << "pause 1" << endl;
cin.ignore();
{
vector<vector<int64> > tmp;
if (no_swap) {
cout << "NOT calling batch.swap(tmp)" << endl;
} else {
cout << "calling batch.swap(tmp)" << endl;
batch.swap(tmp);
}
}
cout << "pause 2" << endl;
cin.ignore();
{
vector<int64> v2;
for (size_t i = 0; i < 12; ++i)
v2.push_back(8000000000);
for (size_t i = 0; i < 10000000; ++i)
batch2.push_back(v2);
}
cout << "pause 3" << endl;
cin.ignore();
}
cout << "pause 4" << endl;
cin.ignore();
}
被注释掉的版本,因此实际上有两个巨大的向量,内存消耗为2 GB - &gt; 3.2 GB - &gt; 2.8 GB - &gt; 2.8 GB。
这是添加了命令行选项的完整代码:
GLIBCXX_FORCE_NEW
在使用中,分配器可以使用实现指定的策略来分配和释放 和启发式。因此,每次调用allocator对象的allocate成员 函数实际上可能不会调用全局运算符new。这种情况也是如此 重复调用deallocate成员函数。
根据此文档,可以通过设置{{1}}来禁用缓存,但这对我不起作用...
答案 1 :(得分:1)
你的CRT实现有可能决定,如果你想要另外12个80MB的连续分配,那么最好不要将内存恢复到操作系统。