FastMM 是否支持保留虚拟内存并调用块来增长数组?
我知道我可以使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,FastMM4(截至我查看的最新版本)没有明确支持这一点。这确实不是您所期望的通用内存管理器中的功能,因为使用 VirtualAlloc 调用来实现它非常简单。
NexusMM4(NexusDB 的一部分)做了一些事情,给你一个类似的结果,但在后台需要它之前不会浪费所有地址空间。
如果您进行初始大量分配(直接通过 GetMem,或间接通过动态数组等),则通过 VirtualAlloc 分配所需大小的内存。
但是,如果该分配随后调整为更大的大小,NexusMM 将使用不同的方式来分配内存,这使得它可以简单地从地址空间取消分配的映射,并在发生进一步重新分配时以更大的大小再次重新映射它。
这可以防止大多数通用内存管理器在重新分配时遇到的两个主要问题:
因此使用 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:
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.