我使用AllocMem / GetMem /新例程分配内存,然后使用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,Rec); // Windows API end; FList.Clear; end;
解决方法
这就是Delphi内存管理器的工作原理 – 它支持它自己的内存缓存,以便它不会将每个释放的内存都返回到系统,而是将其保存在缓存中.下次再分配一个内存,首先尝试在缓存中找到请求的内存,而不是在系统中.这使得内存分配/释放更快.
BTW永远不会使用FreeMem作为具有终身管理字段的记录(如您的示例中的字符串) – 它会导致内存泄漏.改用Dispose
对于具有终身管理字段的记录,也不要使用GetMem(在示例中为注释行) – 它会导致访问冲突.使用新的.