c++ - 从长 vector 中释放内存

标签 c++ stl vector memory-management

我想做的是释放 vector 使用的内存(比如 vector<vector<int>> )我使用了交换技巧,即 v.swap(vector<vector<int>>()) .

然而,我观察到交换技巧适用于短 vector 但不适用于长 vector ,例如我尝试了一个长度为 10,000,000 的 vector ,它占用了 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();
}

最佳答案

James、In silico 和 Max 的评论都是正确的。您希望在调用 batch.swap(tmp) 时释放内存,因为 tmp 是空的。我刚刚在 64 位 Linux 上运行了你的程序,使用 gcc 4.6.0 编译。使用 top 观察内存消耗时,它变为 2 GB -> 1.8 GB -> 1.8 GB。但是,当添加一个 batch2 并在 pause 2 之后填充它时,就像填充 batch 一样,内存消耗不会增加。运行 batch.swap(tmp) 被注释掉的版本,因此实际上有两个巨大的 vector ,内存消耗变为 2 GB -> 3.2 GB -> 2.8 GB -> 2.8 GB。

这是添加了命令行选项的完整代码:

#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();
}

可以找到关于此行为的一些解释 herehere .来自后者:

In use, allocator may allocate and deallocate using implementation-specified strategies and heuristics. Because of this, every call to an allocator object's allocate member function may not actually call the global operator new. This situation is also duplicated for calls to the deallocate member function.

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

关于c++ - 从长 vector 中释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6526983/

相关文章:

c++ - LibGit2 SSH 身份验证失败

c++ - 在 STL 中扩充/索引 priority_queue

STL - 带有迭代器但没有容器的 c++ 类

vector - 将切片附加到向量的惯用方法是什么?

c++ - 从 Truetype 字体中提取 SplineSet/其他信息

C++跨平台编译

c++ - static const 和 constexpr 变量有什么区别?

c++ - 使用大括号而不是 make_pair 会出现错误

c++ - 将字符 vector 转换为字符串的最快方法

C++ vector erase advances 迭代器