我正在使用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时,它说所有内存都被释放了,所以它不是泄漏的问题,因为一切都在运行后很好地清除了。
编辑:
清除后必须出现冲洗。
答案 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()联机帮助页-它暗示了为什么您的代码可以保留内存而不是将其返回给操作系统。