4

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

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

我的用例:假设我创建了一个基于链表的队列容器,并且该列表的每个节点都分配在堆上,因此每次调用 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;
    }
}

`

4

5 回答 5

5

池化是一种非常常见的技术,可以避免频繁的分配和释放。有些人将其视为一种设计模式。通常存在现有的实现,因此重新发明轮子没有任何好处。

您可能想看看问题对象池与动态分配

于 2010-06-01T21:42:58.200 回答
1

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

于 2010-06-01T21:43:17.550 回答
1

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

于 2010-06-01T22:01:57.163 回答
0

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

于 2010-06-01T21:43:31.107 回答
0

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

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

于 2010-06-01T21:50:56.480 回答