“内存缓存”和“内存池”的区别

4
通过阅读《理解Linux网络内部》和《理解Linux内核》这两本书以及其他参考资料,我对“内存缓存”和“内存池”技术感到很困惑,需要一些澄清。
1)它们是相同的技术还是不同的技术?
2)如果不同,是什么造成了区别,或者说有何不同的目标?
3)此外,Slab Allocator如何介入其中?
3个回答

3
关于板块分配器:
假设内存是平的,即您拥有一个4 GB连续内存块。然后,您的程序之一请求256字节的内存,因此内存分配器必须从这4 GB中选择一个适当的256字节块。现在,您的内存看起来像这样:
<============256bytes=======================>
(每个=都是连续的内存块)。一些时间过去了,许多使用内存的程序需要更多的256块或更少,因此最终您的内存可能如下所示:
<==256==256=256=86=68=121===>
因此它变得分散,您美丽的4 GB内存块就没有了踪迹 - 这就是碎片化。现在,板块分配器会跟踪已分配的对象,一旦不再使用它们,它将说该内存已释放,实际上它将保留在某种列表中(您可能想阅读FreeLists)。
现在想象一下,第一个程序放弃了分配的256个字节,然后一个新程序想要有256个字节,所以它可以重复使用最近释放的256个字节,而不必搜索适当连续空间的物理内存来分配新的内存块。这就是你基本上实现内存缓存的方式。这样做可以减少整体上的内存碎片化,因为你可能会遇到内存如此碎片化以至于无法使用,内存管理器必须进行一些魔法来获取适当大小的块。而使用slab分配器可以积极地解决(但不能消除)这个问题。

2
感谢LordDoskias的贡献。然而,那更多是关于碎片化的问题。它并没有解释我关于“内存缓存”和“内存池”的同/异关系问题。 - pepero

0

Linux内存分配器,也称为slab分配器,维护了相似或近似大小的内存对象的常用列表/池。 slab赋予程序员额外的灵活性,可以创建自己的同一大小的常用内存对象池,并根据程序员想要的方式标记、分配、回收和最终销毁它。这个缓存对于您的驱动程序是已知的并且是私有的。但是,在内存压力下,存在高概率的分配失败问题,这在某些驱动程序中可能是不可接受的,那么怎么办呢?最好总是保留一些备用内存,以便我们永远不会感到内存短缺,由于kmem缓存是更通用的池机制,因此我们需要一个可以始终维护所需最少内存的朋友——内存池。


0

旁路缓存 - Linux内核中的缓存管理器有时被称为slab分配器。您可能会反复分配许多相同大小的对象,因此通过使用此机制,您只需分配许多相同大小的对象,然后稍后再使用它们,而无需反复分配许多对象。

内存池只是一种旁路缓存的形式,试图始终保留一些内存列表以供紧急情况使用,因此当创建内存池时,分配函数(slab分配器)会创建一组预分配的对象池,以便在需要时获取它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接