使用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 を解放して、再度必要になったときに自動的にコミットされるようにするにはどうすればよいですか?
警告
David は、大きな (巨大な) 連続するメモリ ページをコミットすると大きなコストがかかると警告しました。
したがって、配列を小さなブロックに分割し、クラス/レコードを使用して内部を抽象化する方が有利な場合があります。