有可能实现一个与数组而不是单个对象一起工作的内存池吗
Is it possible to implement a memory pool that works with arrays instead of single objects?
我知道为单个对象创建内存池很容易,但我需要为数组创建内存池。我目前拥有的内存池有一个指向连续内存块的地址向量和一个指向这些块中每个对象的堆栈,所以当你从池中分配时,你只需弹出堆栈,当你空闲时,你只要将对象的地址推回到它。然而,我也需要一个等效的数组。类似这样的东西:
template<typename T>
class ArrayPool
{
public:
ArrayPool();
~ArrayPool();
T* AllocateArray(int x); //Returns a pointer to a T array that contains 'x' elements.
void FreeArray(T* arr, int x); //Returns the array to the free address list/stack/whatever/
};
这样的事情实施了吗?我认为拥有这样一个池会带来一个大问题——如果确保ALlocateArray返回的数组在内存中是连续的,那么我基本上会像没有内存池一样做。只是当场分配数组。对于普通对象池,每次我只分配1个对象。对于数组,我可能每次都会分配一个不同大小的数组,所以一旦一个数组被释放,它就不会与不同大小的新数组兼容,除非我将数组与一些类似链表的结构粘在一起,但它们不会是连续的。
当前您的分配器利用了所有分配大小相同的事实。这简化并加速了分配和释放,意味着内存碎片是不可能的。
如果必须分配任何大小的数组,那么您需要的是通用分配器,而不是池分配器。下一步该做什么取决于您首先使用池分配器的原因。我可以想到池分配器的另外两个可能相关的功能,可能还有其他功能:
- 所有内存都来自创建池时指定的特定区域
- 通过重置池,可以一次释放所有内存,而无需释放每个单独的分配
如果您自己不需要控制分配的任何特殊功能,那么只需使用vector
或全局operator new
或malloc
来分配内存。如果您确实需要特殊功能,那么您可能希望从货架上取下分配器,而不是实现自己的分配器。如果你真的想了解一个好的内存分配器是如何工作的细节,那么看看http://g.oswego.edu/dl/html/malloc.html也许可以根据您的使用进行调整。
但是,如果你真的需要出于有限的目的手动滚动分配器,那么基本的想法是,你需要一些包含不同大小的空闲块的数据结构(你选择什么),而不是一个总是可以从中获取第一个空闲节点的列表,这样你就可以快速找到一个足够大的块来满足当前的请求。在它大得多的情况下,你可以选择分割块,返回一部分,并将其余部分保留为一个新的较小的空闲块。在两个空闲块相邻的情况下,您可以选择将它们合并为一个更大的空闲块。
一种常见的策略是保留特定大小(例如16、32、64…)的类似池的块列表。如果请求足够小,请使用其中一个来满足它。如果没有,做一些更复杂的事情。但正如我所说,如果你想看到很多技巧协同工作,那么看看dlmalloc。
您可以做的是拥有固定的大小,并且只处理这些大小。例如,第400个32字节数组、200个128b、100个1024b、50个8096b或类似的数组。当有东西要求一个大小为N的数组时,你可以用一个空闲数组来匹配最接近的大小。
每种尺寸需要多少可能需要大量调整。
这将允许您比允许自定义大小更自由地重用阵列。
您到底想从中赢得什么?为什么仅仅将每个数组视为一个对象还不够呢?除非您的内存严重不足,或者构建数组元素的时间确实过多,不能浪费,否则这听起来像是过早优化的经典案例。如果以上是你的问题,在深入研究之前,我会先研究其他数据结构(而不是数组)。你的时间(我想,解决这个问题需要一周左右)比节省几分钱的计算机时间或内存更有价值。
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 将 exprtk 与自定义类的对象一起使用
- 如何将来自 Boost.Python 的map_indexing_suite与自定义而不是标准对象一起使用?
- 将函数指针和对象放在一起
- 将 std::variant 与 gmock 1.8 对象一起使用时编译错误
- 返回对象如何与分配运算符一起工作
- 对象的序列化向量为STD :: String,以与MPI一起使用
- 将 OpenGL 实例化图形与移动对象一起使用
- 如何修复结构播放器对象中的矢量位置,以便它在 Main 中与 me.position 一起使用?
- 在没有返回值优化的情况下将两个对象加在一起时,将创建多少个临时对象
- 如何使用 new 和 delete 与 OpenGL 的缓冲区对象一起使用?
- 如何将指针与对象一起使用;构造函数和破坏者.C
- QtConcurrent::run 是否可以与指向对象的智能指针一起使用
- 有没有一种方法可以将升压信号和插槽与不可复制的对象一起使用
- 有可能实现一个与数组而不是单个对象一起工作的内存池吗
- 如何将自由函数与对象一起使用
- 将 at() 与自定义对象的向量一起使用时的分割错误
- 与对象一起返回时清除了内存指针
- 将GoogleMock与Boost::Shared Pointers一起使用时泄漏的Mock对象
- 在c++中将两个对象添加到一起