pep*_*ero 6 c++ memory-management fragmentation memory-pool
我需要对内存池的概念和实现做一些澄清.
通过维基上的内存池,它说
也称为固定大小块分配,...,由于这些实现由于可变块大小而受到碎片的影响,由于性能的原因,它们不可能在实时系统中使用它们.
"可变块大小如何导致碎片化"如何发生?固定大小的分配如何解决这个问题?这个维基描述对我来说听起来有点误导.我认为通过固定大小的分配或由可变大小引起的碎片不可避免.在内存池上下文中,特定应用程序的特定设计内存分配器可以避免碎片,或者通过限制使用预期的内存块来减少碎片.
同样通过几个实现示例,例如代码示例1和代码示例2,在我看来,使用内存池,开发人员必须非常好地了解数据类型,然后将数据剪切,拆分或组织到链接的内存中块(如果数据接近链表)或分层链接块(如果数据更加层次化,如文件).此外,开发人员似乎必须事先预测他需要多少内存.
好吧,我可以想象这适用于一系列原始数据.C++非原始数据类怎么样,内存模型不是很明显?即使对于原始数据,开发人员是否应该考虑数据类型对齐?
C和C++有好的内存池库吗?
谢谢你的评论!
ser*_*gio 13
可变块大小确实会导致碎片化.看看我附上的照片:
图像(从这里)显示了一种情况,其中A,B和C分配内存块,可变大小的块.
在某些时候,B释放了所有的内存块,突然间你就会出现碎片.例如,如果C需要分配大块内存,那仍然适合可用内存,则无法做到,因为可用内存分为两个块.
现在,如果你考虑每个内存块大小相同的情况,这种情况显然不会出现.
当然,内存池有其自身的缺点,正如您自己所指出的那样.所以你不应该认为内存池是一个神奇的魔杖.它有成本,在特定情况下支付它是有意义的(即内存有限的嵌入式系统,实时约束等).
至于哪个内存池在C++中是好的,我会说它取决于.我在操作系统提供的VxWorks下使用了一个; 从某种意义上说,一个好的内存池在与OS紧密集成时是有效的.实际上,我猜每个RTOS都提供了内存池的实现.
如果您正在寻找通用内存池实现,请查看此内容.
编辑:
从你最后的评论中,在我看来,你可能认为内存池是解决碎片问题的"解决方案".不幸的是,这种情况并非如此.如果你愿意,碎片化是记忆层面熵的表现,也就是说,它是不可避免的.另一方面,内存池是一种管理内存的方式,可以有效地减少碎片的影响(正如我所说,并且正如维基百科所提到的,主要是在特定系统上,如实时系统).这需要付出代价,因为内存池的效率低于"普通"内存分配技术,因为您拥有最小的块大小.换句话说,熵在伪装下重新出现.
此外,这是影响内存池系统效率的许多参数,例如块大小,块分配策略,或者您是否只有一个内存池,或者您有多个具有不同块大小,不同生命周期或不同策略的内存池.
内存管理实际上是一个复杂的问题,内存池只是一种技术,与其他技术相比,它可以改进与其他技术相比的内容并确定其自身的成本.
在您总是分配固定大小的块的情况下,您要么有足够的空间再放置一个块,要么没有。如果有,则该块适合可用空间,因为所有空闲或已用空间的大小都相同。碎片化不是问题。
在具有可变大小块的场景中,您最终可能会得到多个不同大小的独立空闲块。对小于可用总内存大小的块的请求可能无法满足,因为没有一个连续的块足够大。例如,假设您最终有两个独立的 2KB 空闲块,并且需要满足 3KB 的请求。即使有足够的可用内存,这些块都不足以提供这种情况。