有可能实现一个与数组而不是单个对象一起工作的内存池吗

Is it possible to implement a memory pool that works with arrays instead of single objects?

本文关键字:一起 对象 单个 工作 内存 实现 数组 一个 有可能      更新时间:2023-10-16

我知道为单个对象创建内存池很容易,但我需要为数组创建内存池。我目前拥有的内存池有一个指向连续内存块的地址向量和一个指向这些块中每个对象的堆栈,所以当你从池中分配时,你只需弹出堆栈,当你空闲时,你只要将对象的地址推回到它。然而,我也需要一个等效的数组。类似这样的东西:

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 newmalloc来分配内存。如果您确实需要特殊功能,那么您可能希望从货架上取下分配器,而不是实现自己的分配器。如果你真的想了解一个好的内存分配器是如何工作的细节,那么看看http://g.oswego.edu/dl/html/malloc.html也许可以根据您的使用进行调整。

但是,如果你真的需要出于有限的目的手动滚动分配器,那么基本的想法是,你需要一些包含不同大小的空闲块的数据结构(你选择什么),而不是一个总是可以从中获取第一个空闲节点的列表,这样你就可以快速找到一个足够大的块来满足当前的请求。在它大得多的情况下,你可以选择分割块,返回一部分,并将其余部分保留为一个新的较小的空闲块。在两个空闲块相邻的情况下,您可以选择将它们合并为一个更大的空闲块。

一种常见的策略是保留特定大小(例如16、32、64…)的类似池的块列表。如果请求足够小,请使用其中一个来满足它。如果没有,做一些更复杂的事情。但正如我所说,如果你想看到很多技巧协同工作,那么看看dlmalloc。

您可以做的是拥有固定的大小,并且只处理这些大小。例如,第400个32字节数组、200个128b、100个1024b、50个8096b或类似的数组。当有东西要求一个大小为N的数组时,你可以用一个空闲数组来匹配最接近的大小。

每种尺寸需要多少可能需要大量调整。

这将允许您比允许自定义大小更自由地重用阵列。

您到底想从中赢得什么?为什么仅仅将每个数组视为一个对象还不够呢?除非您的内存严重不足,或者构建数组元素的时间确实过多,不能浪费,否则这听起来像是过早优化的经典案例。如果以上是你的问题,在深入研究之前,我会先研究其他数据结构(而不是数组)。你的时间(我想,解决这个问题需要一周左右)比节省几分钱的计算机时间或内存更有价值。