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

发布于 2024-11-15 19:33:07 字数 625 浏览 4 评论 0原文

我知道我可以使用 VirtualAlloc 保留虚拟内存。
例如,我可以申请 1GB 虚拟内存,然后调用其中的第一个 MB,将不断增长的数组放入其中。
当数组增长超过 1MB 时,我会调用第 2MB,依此类推。
这样,当阵列增长时,我不需要在内存中移动阵列,它只是保持在原位,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 支持这个吗?

I know I can reserve virtual memory using VirtualAlloc.
e.g. I can claim 1GB of virtual memory and then call in the first MB of that to put my a growing array into.
When the array grows beyond 1MB I call in the 2nd MB and so on.
This way I don't need to move the array around in memory when it grows, it just stays in place and the Intel/AMD virtual memory manager takes care of my problems.

However does FastMM support this structure, so I don't have to do my own memory management?

Pseudo code:

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

Does FastMM support this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

还在原地等你 2024-11-22 19:33:07

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

NexusMM4(NexusDB 的一部分)做了一些事情,给你一个类似的结果,但在后台需要它之前不会浪费所有地址空间。

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

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

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

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

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

No, FastMM4 (as of the latest version I looked at) does not explicitly support this. It's really not a functionality you would expect in a general purpose memory manager as it's trivially simple to do with VirtualAlloc calls.

NexusMM4 (which is part of NexusDB) does something that gives you a similar result, but without wasting all the address space before it is needed in the background.

If you make an initial large allocation (directly via GetMem, or indirectly via a dynamic array or such) the memory is allocated in just the size needed, via VirtualAlloc.

But if that allocation is then resized to a larger size, NexusMM will use a different way to allocate memory which allows it to simply unmap the allocation from the address space an remap it again, at a larger size, when further reallocs takes place.

This prevents the 2 major problems that most general purpose memory managers have when reallocating:

  • during a normal realloc the existing and new allocation need to be present in the address space at the same time, temporarily doubling the address space and physical memory requirements
  • during a normal realloc, the whole contents of the existing allocation needs to be copied

So with NexusMM you would get all the advantages of what you showed in your pseudo code (with the exception that the first realloc will involve a copy, and that growing your array might change it's address) by simply using normal GetMem/ReallocMem/FreeMem calls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文