加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 为什么要使用FreeMem / Dispose例程来释放内存,但没有

发布时间:2020-12-15 04:26:55 所属栏目:大数据 来源:网络整理
导读:我使用AllocMem / GetMem /新例程分配内存,然后使用FreeMem / Dispose例程释放内存.但是我发现(由Process Explorer),进程的内存大小没有减少. 如果我使用GlobalAllocPtr / HeapAlloc和GlobalFreePtr / HeapFree API,内存大小会减少. 这是我的测试代码: type
我使用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(在示例中为注释行) – 它会导致访问冲突.使用新的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读