从长向量释放内存

时间:2011-06-29 20:40:33

标签: c++ stl vector memory-management

我想要做的是释放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();
}

2 个答案:

答案 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

可以找到herehere对此行为的一些解释。从后者:

  

在使用中,分配器可以使用实现指定的策略来分配和释放   和启发式。因此,每次调用allocator对象的allocate成员   函数实际上可能不会调用全局运算符new。这种情况也是如此   重复调用deallocate成员函数。

根据此文档,可以通过设置{{1}}来禁用缓存,但这对我不起作用...

答案 1 :(得分:1)

你的CRT实现有可能决定,如果你想要另外12个80MB的连续分配,那么最好不要将内存恢复到操作系统。