假设我需要频繁地(任意大小)在堆上分配和删除对象,如果不是删除那些对象,是否有任何性能优势,我会将它返回到某个“池”以便以后重用?
它会通过减少堆分配/释放来获益吗?或者它会比内存分配器性能慢,因为“池”需要管理动态的指针集合。
我的用例:假设我基于链表创建了一个队列容器,并且该列表的每个节点都在堆上分配,因此每次调用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;
}
}
`
答案 0 :(得分:4)
池化是一种非常常见的技术,可以避免频繁的分配和解除分配。一些treat it as a design pattern。 通常存在实现,因此重新发明轮子没有任何好处。
您可能需要查看问题Object pool vs. dynamic allocation
答案 1 :(得分:1)
当我问this question.时,我有类似的担忧。答案可能对您有所了解,特别是那些解决内存碎片问题的答案。
答案 2 :(得分:1)
您可以查看Boost object pool - 了解用法的想法,参考或最佳信息:&gt;
答案 3 :(得分:0)
这是一个特别有用的工具,可以使内存分配更具确定性。如果预先分配生成池的大块,它还可以减少内存碎片。
答案 4 :(得分:0)
根据您的运行时库,对于许多情况,您可能有一个“足够好”的分配器。也就是说,如果你可以证明你有一个特殊的用例,或者你在libc中执行不好的malloc,你应该只为你的应用程序构建一个池分配器。
由于Doug Lea的大部分工作都出现在GNU lib中,您可能希望了解他在A Memory Allocator中的经历。