我正在浏览一些实时操作系统规范,我读到在RTOS中,我们通常不喜欢使用malloc。原因是:对于性能问题,我们不应该使用malloc,因为通过malloc分配内存很耗时,而且跟踪分配的内存的开销也更高。
现在在实时系统中,所有进程都有时间限制,我们通常不使用malloc。我产生了好奇心,并开始研究一些类似于RTOS在运行时如何实际分配内存的问题,我找到了内存池。现在写到内存池实际上意味着固定大小的块allocation.Now内存池的优点是它不会受到碎片的影响。这怎么可能呢?假设我们有3个4字节的池,而应用程序需要10个字节,因此在这种情况下,内存池将受到内部碎片的影响。
内存池是如何工作的,内存是如何分配的?应用程序是否在编译时获取池,就像特定的应用程序将从4字节的池大小中获取3个池一样?如果它们需要的内存无法放入池中,该怎么办?这样的系统中是否存在许多不同大小的内存池?请给我解释一下。
发布于 2012-09-22 23:41:09
那么,碎片将取决于内存池的实现。通常,内存池是固定大小的内存块的池。当某个东西需要这么大的内存块时,它会使用该内存池。因此,没有碎片,因为所有需要这种大小的块的东西都是从这种大小的块池中获取的。
现在,如果特定大小的块池不存在,则可以使用更大大小的池。如果发生这种情况,那么从技术上讲就是碎片,因为分配的内存块的某一部分没有被使用(碎片)。
如果所有内存池都提供了所有所需大小的块,那么就不会有碎片。
发布于 2016-12-02 12:35:01
池不能消除碎片,但它们可以极大地减少碎片,还可能减少分配大量非常小的块的开销。一个很好的方案是一个库,它允许客户端代码为其每个高度可伸缩的结构创建一个池。在创建池时,您需要指定块大小、初始分配和增长的块的数量,以及用于调试的文本名称。
要分配块,需要将池ID传递给分配器。只要池没有空闲块,它就会分配一个连续的块,并使它们可用,并返回其中一个块。每当一个块被释放时,如果该块的块中的所有块都是空闲的,它就会释放该块。
对于debug,有一个例程可以打印所有的池,给出描述,分配的数量,以及可能的其他统计数据,如可用空闲池的数量(如果这个值很高,则存在碎片问题)和曾经分配的最大值。对查找内存泄漏非常有帮助。
对于这种类型的库,最糟糕的情况是子系统分配了大量的块,然后在系统生命周期的早期随机释放了其中的大多数块。许多区块将保持已分配状态,但使用的区块很少。最好的情况(与malloc相比)是需要生命周期变化很大的新块的连续循环,用于必须保持较长时间的系统,如某些嵌入式系统。
这是最简单的,并且最适合单线程应用程序。对于多线程应用程序,必须注意使其线程安全,并且您可能需要模仿malloc()经常在幕后进行的优化,以最小化锁定开销(例如,每个线程的"arenas")。
https://stackoverflow.com/questions/12545044
复制相似问题