使用VirtualAlloc
时我可以(ab)使用以下属性来简化内存管理。
除非实际访问虚拟地址,否则不会分配实际物理页面。
我运行以下代码来分配块。
type
PArrayMem = ^TArrayMem; //pointer
TArrayMem = packed record //as per documentation
RefCount: Integer;
Length: NativeInt;
Elements: Integer;
end;
var
a: array of integer; //dynamic array, structure see above
procedure TForm38.Button1Click(Sender: TObject);
const
AllocSize = 1024 * 1024 * 1024; //1 GB
var
ArrayMem: PArrayMem;
begin
//SetLength(a, 1024*1024*1024); //1G x 8*16
ArrayMem:= VirtualAlloc(nil, AllocSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
ArrayMem.RefCount:= 1;
ArrayMem.Length:= AllocSize div SizeOf(Integer);
a:= @ArrayMem.Elements; //a:= AddressOf(elements)
a[1]:= 10; //testing, works
a[0]:= 4;
a[500000]:= 56; //Works, autocommits, only adds a few k to the used memory
button1.Caption:= IntToStr(a[500000]); //displays '56'
end;
这一切都很棒。如果我的结构增长到1.000.000元素,一切都会有效 但是假设之后我的结构缩小到1.000元素。
如何释放RAM,以便在需要时再次自动提交?
警告
大卫警告我,分配一个大的(巨大的)连续存储页面会带来很大的成本
因此,将数组拆分为较小的块并使用类/记录抽象出内部结构可能更为有利。
答案 0 :(得分:2)
您可以使用VirtualFree
传递MEM_DECOMMIT
标记来停用页面。然后,您可以使用VirtualAlloc
再次提交。
或者您可以使用Windows 8.1中引入的DiscardVirtualMemory
功能。
使用此功能可以丢弃不再需要的内存内容,同时保持内存区域本身的提交。丢弃内存可能会将物理RAM返回给系统。当应用程序再次访问内存区域时,将恢复后备RAM,并且内存的内容未定义。
您可以在对此相关问题的评论中找到有用的内容:New Windows 8.1 APIs for virtual memory management: `DiscardVirtualMemory()` vs `VirtualAlloc()` and `MEM_RESET` and `MEM_RESET_UNDO`