如何强制我的std :: map释放使用的内存?

时间:2010-04-13 11:17:47

标签: c++ memory stl vector map

我正在使用std :: map,我似乎无法将内存释放回操作系统。看起来像,

int main(){
  aMap m;

  while(keepGoing){
    while(fillUpMap){
       //populate m
    }
    doWhatIwantWithMap(m);
    m.clear();//doesnt free memory back to OS

    //flush some buffered values into map for next iteration
    flushIntoMap(m);
  }
}

每个(fillUpmap)分配大约1gig,所以我非常有兴趣在它耗尽所有内存之前将其恢复到我的系统。

我对std :: vector经历了同样的事情,但是我可以通过与空std :: vector交换来强制它释放。这不适用于地图。

当我使用valgrind时,它说所有内存都被释放了,所以它不是泄漏的问题,因为一切都在运行后很好地清除了。

编辑:

清除后必须出现冲洗。

7 个答案:

答案 0 :(得分:13)

m.clear()将内存释放回堆中,但堆实现通常不会将其释放回操作系统(即使它们可以,碎片等问题也很难)。

这是默认分配器的工作方式,如果您为地图指定了自己的分配器,它可能有自己的缓存。但是,即使在这种情况下,它也应该被缓存,以便立即重用。

地图没有像矢量那样的容量与大小的概念。

答案 1 :(得分:3)

这种行为是正常的,运行时库将地图类分配的内存保留给进程,以便下次需要分配内存时,不必转到操作系统。这是一个运行时库优化。

答案 2 :(得分:1)

如果您在堆上创建地图(通过new),删除它将释放它使用的任何内存。

答案 3 :(得分:1)

当我在std :: map中放入一些数据然后调用std :: map :: clear()时,我做了一个简单的测试。

typedef std::map<int, unit_t,std::less<int>,  
     my_allocator<std::pair<const int, unit_t>, 4 > > contaner_t;
contaner_t keys;
keys[1] = 10;
keys[2] = 20;
keys[3] = 30;
keys.clear();

这是我在测试中插入printf的结果:

Allocator # 4, Memory consumption:      56     (allocated   :       56)
Allocator # 4, Memory consumption:     112     (allocated   :       56)
Allocator # 4, Memory consumption:     168     (allocated   :       56)
Allocator # 4, Memory consumption:     112     (deallocated :       56),
Allocator # 4, Memory consumption:      56     (deallocated :       56),
Allocator # 4, Memory consumption:       0     (deallocated :       56),

我认为您可能还应检查您的分配器行为,但我认为您的默认std :: allocator实际上会按预期释放内存,但该内存不会返回给操作系统。顺便问一下你用什么操作系统?

这里的问题是你如何衡量can't seem to free the memory back to the OS.以及如何确定I could force it to free by doing a swap with an empty std::vector.你真的确定分配的内存实际上会回到操作系统吗?

答案 4 :(得分:0)

也许您可以创建自定义分配器,或者只使用Boost's池库。

答案 5 :(得分:0)

交换技巧?我知道你是如何使用矢量等来做的,但我以前没有用地图做过。

答案 6 :(得分:0)

我想你在Linux上。

如果您确实需要最小化应用程序的内存占用量,则可以在清除映射后调用malloc_trim()。我还建议您浏览mallopt()联机帮助页-它暗示了为什么您的代码可以保留内存而不是将其返回给操作系统。