为什么使用FreeMem/Dispose例程释放内存,但没有内存减少?

Leo*_*Leo 10 memory delphi

我使用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.

  • 关于使用Dispose/New进行此类记录的警告+1. (5认同)

Mas*_*ler 11

你看到这个是因为从Windows获取内存是一项昂贵的操作,所以当你使用Delphi的内置内存管理器时,它会缓存一定数量的未使用的内存,因为你很可能很快就会需要它.

如果你释放了大量的内存,你可能会看到它给操作系统带来一些回馈,但是它仍然会在本地保留一些,所以它不需要更快地要求更多内存.

  • 至少OP没有使用任务管理器来测量内存.你不会看到任何外部工具的差异,正如梅森所说,直到你足够自由,堆管理器(快速mm)决定减少其堆池. (4认同)