防止STL容器中的内存释放

时间:2013-06-21 10:07:12

标签: c++ memory-management stl

我有一个我不断重用的STL容器(std :: list)。我的意思是我

  1. 将许多元素推入容器
  2. 在处理过程中删除元素
  3. 清除容器
  4. 冲洗并重复多次
  5. 使用callgrind进行性能分析时,我看到大量对newmalloc)和deletefree)的调用,这些调用非常昂贵。因此,我正在寻找一些方法来优先预分配相当多的元素。我还希望我的分配池继续增加,直到达到高水位线,并且分配池继续挂起到内存,直到容器本身被删除。

    不幸的是标准分配器不断调整内存池的大小,所以我正在寻找一些能够完成上述操作的分配器,而不必自己编写。

    这样的分配器是否存在,我在哪里可以找到这样的分配器?

    我正在使用GCC和使用STLPort的Android工作。

    编辑:展示位置new没问题,我想要最小化的是堆行走,这是很昂贵的。我还希望我的所有对象尽可能地彼此接近,以最大限度地减少缓存未命中。

4 个答案:

答案 0 :(得分:7)

听起来你可能只是使用了错误类型的容器:使用列表,每个元素占用一个单独的内存块,以允许单独的插入/删除 - 因此列表中的每个添加/删除都需要单独的{ {1}}。

如果您可以改用new()/delete(),那么在添加项目之前,您可以std::vector所需的尺寸。

同样,对于删除,通常最好不要单独删除项目。只需在容器上调用reserve即可清空。它


修改:您现在已在评论中明确指出,“在处理期间删除元素”步骤是从列表中间删除元素,并且必须不会使迭代器无效,因此切换到矢量是不合适的。我现在就留下这个答案(为了评论帖子!)

答案 1 :(得分:6)

分配器boost::fast_pool_allocator旨在与std::list一起使用。

文档声称"如果您严重关注性能,请在处理boost::fast_pool_allocator等容器时使用std::list,并在处理容器时使用boost::pool_allocator std::vector"

请注意boost::fast_pool_allocator是一个单例,默认情况下它永远不会释放已分配的内存。但是,它是使用boost::singleton_pool实现的,您可以通过调用静态函数boost::singleton_pool::release_memory()boost::singleton_pool::purge_memory()使其成为可用内存。

答案 2 :(得分:0)

您可以尝试使用http://goog-perftools.sourceforge.net/doc/tcmalloc.html对您的应用进行基准测试,我在某些项目中看到了一些不错的改进(虽然手头没有数字,抱歉)

编辑:似乎代码/下载已移至那里:http://code.google.com/p/gperftools/?redir=1

答案 3 :(得分:-1)

评论太短,所以我会发表我的想法作为答案。

IMO,new / delete只能在这种情况下来自两个地方。

我认为std::list<T>是由某些节点实现的,因为通常的列表是出于各种原因。因此,每次插入和删除元素都必须导致节点的新/删除。此外,如果T类型的对象在c / tor tor中有任何分配和解除分配,它们也会被调用。

您可以通过重复现有节点而不是删除它们来避免重新创建标准内容。如果您想将其压缩到c级,可以使用std::vectorstd::vector::reservestd::array

尽管如此,对于创建的每个对象,必须将其称为析构函数。我认为避免创建和破坏的唯一方法是在重复容器时使用T::operator=,或者如果适合你的话,可以使用一些c ++ 13 move