代码之家  ›  专栏  ›  技术社区  ›  the_drow

非碎片化静态内存池的设计与编码

  •  1
  • the_drow  · 技术社区  · 14 年前

    我以前听过这个词,我想知道如何设计和编码一个。
    如果可以,我应该使用stl分配器吗?
    如何在没有操作系统的设备上完成?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Nim    14 年前

    我会试图描述什么本质上是一个记忆池-我只是在我的头上打这个,已经有一段时间了,我已经实现了一个,如果有什么明显的愚蠢,这只是一个建议!:)

    为了减少碎片,您需要创建一个特定于您在其中分配的对象类型的内存池。本质上,然后将每个分配的大小限制为您感兴趣的对象的大小。您可以实现一个模板化的类,该类具有动态分配块的列表(列表的原因是您可以增加可用空间)。每个动态分配的块本质上都是一个t数组。

    然后您将得到一个“自由”列表,它是一个单独链接的列表,头部指向下一个可用块。分配就是简单地返回头部。您可以在块本身中覆盖链接列表,即每个“块”(表示t的对齐大小),本质上是t和链接列表中的节点的联合,当分配时,它是t,当释放时,它是列表中的节点。!!!有明显的危险!!或者,您可以分配一个单独的(和受保护的块,这会增加开销)来保存块中的地址数组。

    分配很简单,遍历块列表并从第一个可用块开始分配,释放也很简单,您需要做的额外检查是找到从中分配该块,然后更新头指针。(注意,您需要使用placement new或override the operator new/delete in t-有很多方法可以解决这个问题,google是您的朋友)

    我认为“静态”意味着所有t类型的对象都有一个单独的内存池。缺点是对于每个t,必须有一个单独的内存池。您可能很聪明,并且有一个管理不同大小池的单个对象(例如,使用指向池对象的指针数组,其中索引就是对象的大小)。

    上一段的重点是准确地概述这是多么的复杂,就像上面的rc所说的,在你做之前一定要确定你需要它-因为它可能会带来比可能需要的更多的痛苦!

    2。 如果stl分配器满足您的需要,那么就使用它,它是由一些非常聪明的人设计的,他们知道自己在做什么——然而,它是为一般情况而设计的,如果您知道如何分配对象,那么您可以使上述的执行速度更快。

    三。 您需要能够以某种方式分配内存(硬件支持或某种类型的HAL-无论什么),否则我不确定您的程序将如何工作?

    4。 常规的malloc/new在封面下做了很多事情(谷歌是你的朋友,我的答案已经是一篇文章!)我上面描述的简单分配器不是可重入的,当然您可以用互斥函数包装它以提供一点覆盖,即使这样,我也会冒险说,简单分配器执行数量级的速度会比普通malloc/free快。

    但是,如果您正处于优化的这个阶段——假设您已经耗尽了优化算法和数据结构使用的可能性?

        2
  •  3
  •   Community CDub    8 年前

    我建议您应该知道,在编写自己的内存分配器之前,您需要一个非碎片化的内存分配器。标准库提供的通常就足够了。

    如果您需要一个,减少碎片的一般想法是一次抓取大的内存块并从池中分配,而不是要求操作系统零星地在堆中高度变化的位置为您提供堆内存,并与许多其他大小不同的对象分散在一起。由于专用内存分配器的作者对从池中分配的对象的大小以及这些分配是如何发生的有更多的了解,因此分配器可以比一般用途分配器(如STL提供的分配器)更有效地使用内存。

    您可以查看内存分配器,例如 Hoard 它在减少内存碎片的同时,还可以通过提供特定于线程的堆来提高性能,从而减少争用。这可以帮助您的应用程序更线性地扩展,尤其是在多核平台上。

    可以找到有关多线程分配器的更多信息 here .