1

我知道我可以使用 VirtualAlloc 保留虚拟内存。
例如,我可以申请 1GB 的虚拟内存,然后调用其中的第一个 MB 来放入我不断增长的数组。
当数组超过 1MB 时,我会调用第 2 个 MB,依此类推。
这样,当阵列增长时,我不需要在内存中移动阵列,它只是保持原位,英特尔/AMD 虚拟内存管理器会处理我的问题。

但是 FastMM 是否支持这种结构,所以我不必自己进行内存管理?

伪代码:

type
  PBigarray = ^TBigarray;
  TBigArray = array[0..0] of SomeRecord;

....

begin
  VirtualMem:= FastMM.ReserveVirtualMemory(1GB);
  PBigArray:= FastMM.ClaimPhysicalMemory(VirtualMem, 1MB);
....

procedure GrowBigArray
begin
  FastMM.ClaimMorePhysicalMemory(PBigArray, 1MB {extra});
  //will generate OOM exception when claim exceeds 1GB

FastMM 支持这个吗?

4

1 回答 1

3

不,FastMM4(截至我查看的最新版本)不明确支持这一点。这实际上不是您在通用内存管理器中期望的功能,因为使用 VirtualAlloc 调用非常简单。

NexusMM4(它是 NexusDB 的一部分)可以为您提供类似的结果,但不会在后台需要之前浪费所有地址空间。

如果您进行初始大分配(直接通过 GetMem,或间接通过动态数组等),则通过 VirtualAlloc 以所需的大小分配内存。

但是,如果该分配随后被调整为更大的大小,NexusMM 将使用不同的方式来分配内存,这允许它简单地从地址空间取消映射分配,并在发生进一步重新分配时以更大的大小再次重新映射它。

这可以防止大多数通用内存管理器在重新分配时遇到的两个主要问题:

  • 在正常重新分配期间,现有分配和新分配需要同时存在于地址空间中,暂时使地址空间和物理内存需求加倍
  • 在正常重新分配期间,需要复制现有分配的全部内容

因此,使用 NexusMM,您只需使用普通的 GetMem/ReallocMem/FreeMem 调用即可获得伪代码中显示的所有优点(除了第一个 realloc 将涉及副本,并且增加数组可能会更改其地址) .

于 2011-06-17T13:53:28.100 回答