1

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

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

4

1 回答 1

2

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

或者您可以使用DiscardVirtualMemoryWindows 8.1 中引入的功能。

使用此函数丢弃不再需要的内存内容,同时保持内存区域本身已提交。丢弃内存可能会将物理 RAM 返还给系统。当应用程序再次访问该内存区域时,将恢复后备 RAM,并且内存的内容未定义。

您可能会在对此相关问题的评论中找到一些有用的信息:用于虚拟内存管理的新 Windows 8.1 API:`DiscardVirtualMemory()` vs `VirtualAlloc()` and `MEM_RESET` and `MEM_RESET_UNDO`

于 2016-03-08T15:27:06.813 回答