【问题标题】:How do I force my std::map to deallocate memory used?如何强制我的 std::map 释放使用的内存?
【发布时间】:2011-02-07 09:53:20
【问题描述】:

我正在使用 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 时,它说所有内存都已释放,因此泄漏不是问题,因为运行后一切都很好地清除了。

编辑:

flush 必须出现在 clear 之后。

【问题讨论】:

  • 请注意,您的操作系统可能会在您尝试分配内存时分配地址空间,但仅在您触摸内存时才分配真实的物理 RAM。如果您不再使用该 RAM 但其他程序需要它,则其内容将被换出到磁盘。因此,释放内存实际上会释放 RAM。

标签: c++ memory stl vector map


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    这种行为是正常的,运行时库保持映射类分配的内存可供进程使用,这样下次它需要分配内存时就不必去操作系统了。这是一个运行时库优化。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        当我将一些数据放入 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. 你真的确定分配的内存实际上会回到操作系统吗?

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

            我猜你是在 Linux 上。

            如果你真的需要最小化你的应用程序的内存占用,你可以在清除地图后调用malloc_trim()。我还建议您看一下 mallopt() 手册页 - 它提供了一些关于为什么您的代码可以保留内存而不是将其返回给操作系统的提示。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-08-13
              • 2015-10-25
              • 2016-12-24
              • 1970-01-01
              • 2015-11-06
              • 1970-01-01
              • 2010-10-17
              • 1970-01-01
              相关资源
              最近更新 更多