FastMM是否支持保留虚拟内存并调用块来增长数组?

时间:2011-06-17 11:42:44

标签: delphi virtual-memory fastmm

我知道我可以使用VirtualAlloc预留虚拟内存 例如我可以声称1GB的虚拟内存然后调用它的第一个MB来增加我的成长阵列 当阵列增长超过1MB时,我会调用第二个MB,依此类推 这样我就不需要在内存中移动数组,当它增长时,它就会保持原位,而Intel / 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是否支持此功能?

1 个答案:

答案 0 :(得分:3)

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

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

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

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

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

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

因此,使用NexusMM,您可以通过简单地使用普通的GetMem / ReallocMem获得您在伪代码中显示的所有优点(除了第一个realloc将涉及副本,并且增加数组可能会改变它的地址) / FreeMem调用。