【问题标题】:Recycle Freed Objects回收释放的对象
【发布时间】:2011-02-26 13:38:53
【问题描述】:

假设我需要经常在堆上分配和删除对象(任意大小),如果我不删除这些对象,而是将其返回到某个“池”以供以后重用,是否有任何性能优势?

它会通过减少堆分配/释放来带来好处吗?还是会比内存分配器性能更慢,因为“池”需要管理指针的动态集合。

我的用例:假设我创建了一个基于链表的队列容器,并且该链表的每个节点都分配在堆上,因此每次调用 push() 和 pop() 都会分配和取消分配该节点:

`

template <typename T> struct QueueNode {
    QueueNode<T>* next;
    T object;
}

template <typename T> class Queue {
    void push(T object) {
        QueueNode<T>* newNode = QueueNodePool<T>::get(); //get recycled node
        if(!newNode) {
            newNode = new QueueNode<T>(object);
        }
        // push newNode routine here..
    }
    T pop() {
        //pop routine here...
        QueueNodePool<T>::store(unusedNode); //recycle node
        return unusedNode->object;
    }
}

`

【问题讨论】:

  • 我的另一个问题是假设我需要使用队列或列表来管理回收节点,那么每次调用 push() 时,实际上是在池上执行 pop() 并执行 push() 到队列,这将是两倍的过程,是否明智?

标签: c++ memory-management queue allocation recycle


【解决方案1】:

池是一种非常常见的技术,可以避免频繁的分配和释放。一些treat it as a design pattern。 通常有现有的实现,因此重新发明轮子没有任何好处。

你可能想看看Object pool vs. dynamic allocation的问题

【讨论】:

    【解决方案2】:

    当我问this question. 时,我也有类似的担忧,答案可能对你很有见地,尤其是那些解决内存碎片问题的答案。

    【讨论】:

      【解决方案3】:

      您可以查看Boost object pool——以获取想法、参考或最佳用法:>

      【讨论】:

        【解决方案4】:

        这是一个特别有用的工具,可以使内存分配更具确定性。如果您预先分配生成池的大块,它还可以减少内存碎片。

        【讨论】:

          【解决方案5】:

          根据您的运行时库,在许多情况下您可能有一个“足够好”的分配器。也就是说,如果您可以证明您有特殊用例或 libc 中的 malloc 实现不佳,您应该只为您的应用程序构建池分配器。

          由于 Doug Lea 的大部分工作都包含在 GNU 库中,您可能想在 A Memory Allocator 中了解他的经验。

          【讨论】:

          • 上次我检查时,glibc 附带的默认分配器已经为小对象(最多 16 个字节,如果我没记错的话……或者是 64 个?) .
          • @Emile,感谢您提供的额外信息。我猜自定义池的最大理由是知道您的目标客户将使用什么 libc。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-18
          • 2011-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多