C++ 编写内存管理器并对内存进行碎片整理

C++ 编写内存管理器并对内存进行碎片整理,c++,memory-management,C++,Memory Management,这个想法是编写一个内存管理器,一次分配一堆内存,以最小化malloc和空闲调用。我自己写过两次,但都遇到了内存碎片整理的问题 您可以每隔一段时间检查一个块是否为空,如果为空则删除它。但假设每个块有100个字节,首先分配20个字节的内存,这将创建一个新的100字节块,因为还不存在块,然后分配80个字节,这将填充第一个块,然后再分配20个字节,这将创建另一个新块,因为第一个块已满,然后释放第二个分配(80字节),剩下两个块,其中只使用前20个字节,这意味着您已分配100个字节,可以通过将第二个块中的

这个想法是编写一个内存管理器,一次分配一堆内存,以最小化malloc和空闲调用。我自己写过两次,但都遇到了内存碎片整理的问题

您可以每隔一段时间检查一个块是否为空,如果为空则删除它。但假设每个块有100个字节,首先分配20个字节的内存,这将创建一个新的100字节块,因为还不存在块,然后分配80个字节,这将填充第一个块,然后再分配20个字节,这将创建另一个新块,因为第一个块已满,然后释放第二个分配(80字节),剩下两个块,其中只使用前20个字节,这意味着您已分配100个字节,可以通过将第二个块中的20个字节移动到第一个块并删除第二个块来释放这些字节

以下是我遇到的问题:

  • 你不能移动内存,因为这意味着所有指向该内存的指针都必须更新,而要做到这一点,你需要知道它们的地址,而你不需要知道它们的地址
  • 100字节是一个非常小的块大小,如果我想在内存中存储一个非常低分辨率(64,64)的ARGB图像怎么办?这将使用16KB的内存,移动所有这些内存可能比根本不编写内存管理器还要慢
  • 写一个自定义内存管理器值得吗

    写一个自定义内存管理器值得吗

    这是在征求意见,但我会尽量给出一个真实的答案

    大多数操作系统和语言支持库附带的内存分配器通常都具有很高的质量,旨在解决您遇到的问题类型(碎片和性能)以及其他问题。它们与通用内存分配器一样好

    如果应用程序具有可利用的特定分配模式,则可以比提供的内存分配器做得更好(稍微好一点)。这是很少见的,但您通常可以通过使某些东西比通用内存管理器简单得多来利用它

    你不能到处移动记忆

    对。大多数现代系统甚至不尝试移动内存——它们从一开始就试图避免碎片化(通常是通过聚集大小类似的分配)

    旧系统(没有虚拟内存管理器的系统)有时使用具有额外间接层的内存管理器。分配器不会返回指向已分配内存的指针,而是返回一个“句柄”,该句柄可以简单到内存管理器维护的表中的索引。当用户想要实际访问内存时,他们会“锁定”它。内存管理器可以在未锁定的内存中自由移动(例如,为了消除碎片),因为句柄提供了额外的间接级别

    如果我想存储一个非常低分辨率(64,64)的ARGB图像怎么办


    大多数内存管理器都提供了一系列大小,这样大的分配就不会被分割到n个较小的块中。大多数都会向系统分配器投入非常大的分配,在虚拟内存操作系统上,系统分配器通常可以解决问题,除非进程地址空间过于分散。

    看看buddy systems-您是否有需要解决的实际性能问题?如果不是,那么我会说这是过早的优化。大多数常用的malloc/free实现都是由对问题领域有深入了解的有才华和经验的程序员编写的,然后根据实际使用中发现的任何缺陷,经过一段时间的改进。这并不意味着它们是最好的实现,但它表明您不太可能在第一次尝试时做得更好。虽然问题有点不同,但我认为您可能会发现这个答案很有用:JesperJuhl因为我编写代码是为了好玩,所以我所做的一切都是不成熟的,因为我可能永远不会在实践中使用它。NeilButterworth我不知道这是如何解决碎片问题的,分配3个块并删除第二个块仍然会留下未使用的内存。rici当两个进程同时调用malloc时,一个进程需要等待另一个进程完成,为单线程应用程序编写自己的管理器可能会更快,我不确定,因为我还没有编写一个。