【问题标题】:Does FastMM support reserving virtual memory and calling in chunks to grow an array?FastMM 是否支持保留虚拟内存并调用块来增长数组?
【发布时间】:2011-06-17 11:42:44
【问题描述】:

我知道我可以使用 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 支持这个吗?

【问题讨论】:

  • 这具有成为XY problem 的特征。我猜你的真正问题是什么,但我怀疑你正遭受地址空间碎片的困扰,因为你的代码需要大的连续内存块。如果是这样,那么最好的解决方案是分配不连续的块,然后在幕后将它们拼凑在一起,使这些较小的块看起来像一个连续的块。
  • 您要问的是高度专业化的行为,VirtualAlloc 可以轻松处理;为什么通用内存管理器会这样做?
  • @David,感谢您关注我。我还没有内存碎片,因为我还没有编写程序:-)。我知道我有一个程序会使用所有可用内存,所以我正在研究我的选择。这不会变成一个冗长的问答,简单的是/否就可以了,我想这不是。
  • @Johan 是的,我认为答案是不。当您开始编写程序时,我可以帮助您解决地址空间碎片问题。我相信您非常了解 IMAGE_LARGE_ADDRESS_AWARE。
  • @David,我不知道它叫那个,但我知道你可以要求 Windows 给你更多的虚拟内存。

标签: delphi virtual-memory fastmm


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2012-06-30
    • 2015-11-23
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 2013-09-08
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多