【问题标题】:Memory compactor in C?C中的内存压缩器?
【发布时间】:2011-11-16 06:42:14
【问题描述】:

我有一个模拟最佳内存管理的程序。 基本上,虽然孔列表中有可用的孔,对于我们尝试分配的进程来说足够大,但进程被分配并添加到进程列表中。然而,最终,我们到达了一个洞变得非常碎片化的地步,我们需要执行压缩。

执行此操作的最简单方法显然是创建一个新列表并按顺序添加所有进程。但是,这不太现实,因为在现实世界中,您将没有空间来移动内容并创建新列表。

你能想出一种方法将所有进程推到内存的一端,而将空闲空间推到另一端吗?基本上,它的设置就像这个孔数组(孔是包含起始索引和大小的结构)和进程数组(进程也是包含进程 ID、起始索引和大小的结构)。

【问题讨论】:

  • 你没有提到你正在运行的操作系统——所以基本上你的程序没有真正的内存地址,所以它没有真正的漏洞?你真的有这些洞吗?那么什么操作系统呢?
  • 请向我们提供有关您的问题的更多背景信息,特别是操作系统和分配的粒度。例如,如果您正在谈论 linux 系统上的用户空间(= 虚拟内存),我的猜测是您的所有问题都没有多大意义。在这样的系统上地址空间的连续性只是虚构的,在幕后操作系统具有内存页面到物理内存的映射功能,这根本不是线性的。重组虚拟内存没有多大意义。
  • 你在这里问什么有点不清楚。您正在尝试在用户空间中实现大多数 VMM 的行为?看起来您将其视为垃圾箱包装问题,这就是为什么我对您正在做什么感到有些困惑。
  • 假设我们正在处理物理内存并且进程在从一个地方移动到另一个地方时被重新定位(在修补地址的意义上)是否正确?

标签: c memory-management data-structures


【解决方案1】:

您可以将分配的内存一个接一个地洗牌到可用内存的末尾。

伪代码:

sort procs by start_index                           (descending)
avail_end = END_OF_MEM - p[0].size                  (adjust alignment)

for p in procs

     memmove( avail_end, p.start_index , p.size )
     avail_end = avail_end  - p.size

这应该会在可用内存的开头产生一个空闲内存块。您也可以在一个区域移动后(达到时间阈值后)停止此功能并稍后继续(通过测试后续进程分配区域之间是否存在间隙,以跳过不必要的移动)。

【讨论】:

    【解决方案2】:

    如果孔的数组是按起始索引排序的,您可以遍历数组并取两个孔并将其间的内存块移动到第一个孔的起始索引。


    进一步说明:

    每个洞都有一个等于start_index + size 的起始索引和一个结束索引。 通过比较第一个洞的结束索引和第二个洞的开始索引,你可以得到介于两者之间的内存块的大小。然后你可以对内存块做一个memmove到第一个起始索引。

    【讨论】:

      【解决方案3】:

      释放内存(并创建一个洞)时,您是否已经将它与相邻的洞合并?否则,这是减少碎片化的好主意。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-26
        • 1970-01-01
        • 2010-12-31
        • 2020-03-03
        • 2016-08-21
        • 1970-01-01
        • 2010-09-18
        • 1970-01-01
        相关资源
        最近更新 更多