【问题标题】:Why does my program's memory not release?为什么我的程序内存没有释放?
【发布时间】:2015-06-14 06:23:16
【问题描述】:
#include <iostream>
#include <string>
#include <deque>
#include <vector>
#include <unistd.h>
using namespace std;
struct Node
{
    string str;
    vector<string> vec;
    Node(){};
    ~Node(){};
};
int main ()
{
    deque<Node> deq;
    for(int i = 0; i < 100; ++i)
    {
        Node tmp;
        tmp.vec.resize(100000);
        deq.push_back(tmp);
    }
    while(!deq.empty())
    {
        deq.pop_front();
    }
    {
        deque<Node>().swap(deq);
    }
    cout<<"releas\n";
    sleep(80000000);
    return 0;
}

通过top,我发现我的程序内存大约是61M,为什么?如果Node 中有复制构造函数也没关系。我想知道为什么,而不是如何使其正确。

gcc (GCC) 4.9.1, centos

【问题讨论】:

  • 删除 C++ 对象只是使内存可用于将来的分配,它不会将其返回给操作系统。
  • 是什么让你认为它不应该是 61mb?
  • @CaptainObvlious 他的问题是为什么在他执行将它们全部从双端队列中弹出的循环之后它没有下降。

标签: c++ memory deque


【解决方案1】:

如果容器是vector,你可以使用swap释放内存,容器是deque,你应该使用clear释放内存,像这样:

int main ()
{
    deque<Node> deq;
    for(int i = 0; i < 100; ++i)
    {
        Node tmp;
        tmp.vec.resize(100000);
        deq.push_back(tmp);
    }
    while(!deq.empty())
    {
        deq.pop_front();
    }
    deq.clear();
    // Or, you should try to use `deque<Node>().swap(deq);`, not `local`.

    cout<<"releas\n";
    sleep(80000000);
    return 0;
}

【讨论】:

  • 对我没用,你呢?
  • 这仍然可能不会减少他的进程大小,因为清除双端队列不会将内存返回给操作系统。
【解决方案2】:

通常,new/deletemalloc/realloc/free 使用sbrk() 或特定于操作系统的等效项从操作系统中安排更多内存,然后按照他们喜欢的方式划分页面以满足程序的分配请求。尝试将小页面释放回操作系统是不值得费心的 - 太多额外的开销跟踪那些/不属于池的页面,重新请求它们等等。在内存不足的情况下,正常的缓存机制将允许很长时间- 无论如何都要从物理 RAM 中换出未使用的内存页面。

FWIW,GNU libC 的 malloc 等。对特别大的请求进行例外处理,以便在程序终止之前完全释放它们以供操作系统/其他程序使用;引用the NOTES section here:

当分配大于MMAP_THRESHOLD 字节的内存块时,glibc malloc() 实现将内存分配为私有匿名映射 使用mmap(2)。 MMAP_THRESHOLD 默认为 128 kB,但 使用mallopt(3) 进行调整。使用mmap(2) 执行的分配是 不受RLIMIT_DATA 资源限制的影响(请参阅getrlimit(2))。

【讨论】:

  • 这是正确的答案,老实说人们应该更好地谷歌,我认为这个问题已经被问过几十次了。
猜你喜欢
  • 2010-10-01
  • 2011-05-25
  • 2011-05-26
  • 2018-11-08
  • 2021-10-03
  • 2021-08-08
  • 1970-01-01
相关资源
最近更新 更多