如何(临时)从 VirtualAlloc 释放内存?

How to (temporary) release memory from VirtualAlloc?

当使用 VirtualAlloc 时,我可以(ab)使用下面的 属性 来简化内存管理。

Actual physical pages are not allocated unless/until the virtual addresses are actually accessed.

我运行下面的代码来分配块。

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 以便在再次需要时自动神奇地提交?

警告
大卫警告我,分配一个提交的大(巨大)连续内存页会带来很大的成本。
因此,将数组拆分为更小的块并使用 class/record 抽象出内部结构可能更有利。

您可以使用 VirtualFree 传递 MEM_DECOMMIT 标志取消提交页面。然后您可以使用 VirtualAlloc.

再次提交

或者您可以使用 Windows 8.1.

中引入的 DiscardVirtualMemory 函数

Use this function to discard memory contents that are no longer needed, while keeping the memory region itself committed. Discarding memory may give physical RAM back to the system. When the region of memory is again accessed by the application, the backing RAM is restored, and the contents of the memory is undefined.

你可能会在这个相关问题的评论中找到有用的东西: