我需要一些关于内存池的概念和实现的澄清。
在wiki上的内存池上,它说
也称为固定大小块分配,.由于这些实现由于变块大小而受到碎片影响,因此由于性能的原因,无法在实时系统中使用它们。
“可变块大小导致碎片”是如何发生的?如何固定大小的分配可以解决这一问题?这个维基描述听起来有点误导我。我认为,固定大小的分配或可变大小不会避免碎片。在内存池上下文中,为特定应用程序设计的特定内存分配器避免了碎片,或者通过限制地使用预定的内存块来减少碎片。
另外,通过几个实现示例(例如,代码示例1和代码示例2 ),在我看来,要使用内存池,开发人员必须非常清楚数据类型,然后将数据剪切、拆分或组织到链接内存块(如果数据接近链接列表)或层次链接块(如果数据是分层的,比如文件)。此外,开发人员似乎必须事先预测他需要多少内存。
好吧,我可以想象这对于一个原始数据数组是很好的。那么C++非原始数据类呢?在这些类中,内存模型并不明显?即使对于原始数据,开发人员也应该考虑数据类型对齐吗?
C和C++有很好的内存池库吗?
谢谢您的评论!
发布于 2011-07-19 13:44:51
在总是分配固定大小块的情况下,要么有足够的空间再分配一个块,要么没有。如果有,块就适合可用的空间,因为所有空闲或使用的空间都是相同大小的。不成体系不是问题。
在具有可变大小块的场景中,您可以得到多个不同大小的空闲块。对于小于空闲内存总量的块的请求可能是无法满足的,因为没有一个足够大的连续块。例如,假设您最终有两个独立的2KB的空闲块,并且需要满足3KB的请求。这两个块都不足以满足这一点,即使有足够的内存可用。
发布于 2011-07-19 13:37:37
可变块大小确实会导致碎片。请看我附上的图片:

图像(从这里开始)显示了A、B和C分配内存块、可变大小块的情况。
在某种程度上,B释放了它所有的内存块,然后突然出现了碎片。例如,如果C需要分配一大块内存,这仍然适合于可用内存,它不能这样做,因为可用内存被分割成两个块。
现在,如果考虑到每个内存块大小相同的情况,这种情况显然不会出现。
当然,内存池也有自己的缺点,正如您自己所指出的。所以你不应该认为一个内存池是一个神奇的魔杖。它是有成本的,在特定情况下(即内存有限的嵌入式系统、实时约束等)支付是有意义的。
至于在C++中哪个内存池是好的,我要说它取决于。我使用了操作系统提供的VxWorks下的内存池;从某种意义上说,一个好的内存池在与操作系统紧密集成时是有效的。实际上,我想每个RTOS都提供了一个内存池的实现。
如果您正在寻找通用内存池实现,请查看这。
编辑:
从您最后的评论来看,在我看来,您可能认为内存池是解决碎片问题的“解决方案”。不幸的是,情况并非如此。如果你愿意,碎片化是熵在记忆层次上的表现,也就是说,它是不可避免的。另一方面,内存池是一种管理内存的方式,能够有效地减少碎片的影响(正如我所说的,而且正如wikipedia所提到的,主要是在特定的系统上,如实时系统)。这需要付出代价,因为内存池可能比“正常”内存分配技术的效率要低,因为您有最小的块大小。换句话说,熵在伪装下再次出现。
此外,这些参数都会影响内存池系统的效率,例如块大小、块分配策略,或者是只有一个内存池,还是有几个具有不同块大小、不同寿命或不同策略的内存池。
内存管理确实是一个复杂的问题,而内存池只是一种技术,它和其他任何技术一样,与其他技术相比改进了事物,并确定了自己的成本。
发布于 2011-07-19 13:42:59
固定大小和可变大小的内存池都将具有碎片特性,即在使用的内存块之间会有一些空闲的内存块。
对于可变大小,这可能会导致问题,因为可能没有足够大的空闲块来满足特定的请求大小。
另一方面,对于固定大小的池,这不是问题,因为只能请求预定义大小的一部分。如果有空闲空间,则保证其足够大(1/1)。
https://stackoverflow.com/questions/6747959
复制相似问题