内存池与malloc

时间:2012-09-22 15:20:34

标签: operating-system real-time rtos

我正在阅读一些实时操作系统规范,我读到在RTOS中我们通常不喜欢使用malloc。其原因如下:对于性能问题,我们不应该使用malloc,因为通过malloc分配内存非常耗时,并且跟踪分配的内存的开销也更高。

现在在实时系统中,时间约束与所有进程一起存在,我们一般不使用malloc。我好奇并开始研究有点像在RTOS中运行时实际分配内存的方式,我找到了内存池。现在有人写道,内存池实际上意味着固定大小的块分配。内存池的优点是它不会受到碎片的影响。这怎么可能?假设我们有3个4字节的池,并且应用程序需要10个字节,因此在这种情况下,内存池将受到内部碎片的影响。

内存池如何工作以及如何分配内存?应用程序是否在编译时获取池,特定应用程序将从池大小为4字节获得3个池?如果它们需要不适合池的内存,该怎么办?这样的系统中是否存在许多不同大小的内存池?请解释一下。

2 个答案:

答案 0 :(得分:1)

好吧,碎片将取决于内存池的实现。通常,内存池是固定大小的内存块池。当某些东西需要一块这样大小的内存时,它会进入该池。因此,没有碎片,因为想要一个大小块的所有东西都从这个大小的块池中获取它。

现在,如果不存在特定大小的块池,则可以使用更大的池。如果发生这种情况,那么技术上就会出现碎片,因为未使用(碎片化)已分配内存块的某个部分。

如果所有内存池都提供了所有必需大小的块,那么就不会出现碎片。

答案 1 :(得分:0)

池不会消除碎片,但它们可以大大减少碎片,并且还可能减少分配大量非常小的块的开销。一个好的方案是一个库,它允许客户端代码为每个高度缩放的结构创建一个池。在创建池时,您可以指定块大小,最初分配和增长的块数,以及用于调试的文本名称。

要分配块,请将池ID传递给分配器。每当池没有空闲块时,它就会分配一个连续的块块并使它们可用,并返回其中一个块。每当释放一个块时,如果该块的块中的所有块都是空闲的,则释放该块。

对于调试,有一个例程打印所有池,给出描述,分配的数量,以及可能的其他统计数据,如可用的免费数量(如果这是高,有碎片问题)和最大永远分配。非常有助于发现内存泄漏。

此类库的最坏情况是子系统分配大量块,然后在系统生命周期的早期释放其中的大部分块。大量的块将继续分配,但使用的块很少。最好的情况(与malloc相比)是需要连续循环,需要具有不同寿命的新块,对于需要长时间保持不变的系统,如某些嵌入式系统。

这是最简单的,最适合单线程应用程序。对于多线程应用程序,必须注意使其成为线程安全的,并且您可能需要模仿malloc()经常在封面下进行的优化以最小化锁定开销(例如,每线程"竞技场& #34;。)