我使用AllocMem/GetMem/New例程来分配内存,然后使用FreeMem/Dispose例程来释放内存.但我发现(通过Process Explorer)进程的内存大小没有减少.
如果我使用GlobalAllocPtr/HeapAlloc和GlobalFreePtr/HeapFree API,内存大小将减少.
这是我的测试代码:
type
TMyRec = record
Name: string;
TickCount: Cardinal;
Buf: array[0..1024 - 1] of byte;
end;
PMyRec = ^TMyRec;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormDestroy(Sender: TObject);
begin
FList.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FList := TList.Create;
ReportMemoryLeaksOnShutdown := true;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
Size: Integer;
Rec: PMyRec;
Heap: Cardinal;
begin
Size := SizeOf(TMyRec);
Heap := GetProcessHeap;
for I := 0 to 2000 - 1 do
begin
Rec := AllocMem(Size); // Delphi routine
//GetMem(Rec, Size); // Delphi routine
//New(Rec); // Delphi routine
//Rec := GlobalAllocPtr(GPTR, Size); // Windows API
//Rec := HeapAlloc(Heap, HEAP_ZERO_MEMORY, Size); // Windows API
FList.Add(Rec);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i: Integer;
Size: Integer;
Rec: PMyRec;
Heap: Cardinal;
begin
Size := SizeOf(TMyRec);
Heap := GetProcessHeap;
for i := FList.Count - 1 downto 0 do
begin
Rec := PMyRec(FList.Items[i]);
FreeMem(Rec, Size); // Delphi routine
//Dispose(Rec); // Delphi routine
//GlobalFreePtr(Rec); // Windows API
//HeapFree(Heap, 0, Rec); // Windows API
end;
FList.Clear;
end;
Run Code Online (Sandbox Code Playgroud)
klu*_*udg 24
这就是Delphi内存管理器的工作原理 - 它支持它自己的内存缓存,因此它不会将每个释放的内存返回给系统,而是将其保存在缓存中.下次它会分配一个内存,它首先尝试在缓存中找到请求的内存,而不是在系统中.这使得内存分配/释放更快.
BTW从不FreeMem用于具有生命周期管理字段的记录(如在您的示例中为ex字符串) - 它会导致内存泄漏.请Dispose改用.
也永远不会GetMem 用于具有生命周期管理字段的记录(示例中的注释行) - 它会导致访问冲突.使用New.
Mas*_*ler 11
你看到这个是因为从Windows获取内存是一项昂贵的操作,所以当你使用Delphi的内置内存管理器时,它会缓存一定数量的未使用的内存,因为你很可能很快就会需要它.
如果你释放了大量的内存,你可能会看到它给操作系统带来一些回馈,但是它仍然会在本地保留一些,所以它不需要更快地要求更多内存.