如何确定特定组件或类使用了多少内存?

时间:2013-03-25 18:49:48

标签: delphi memory components

是否可以检索delphi中单个组件使用的内存量?

我正在从互联网上下载简单的字符串,我看到在下载过程结束时内存使用量达到了1 GB,但是当我查看包含我下载的所有内容的已保存文件时,文件只是在千字节范围内,显然组件正在发生变化,即使我将它们销毁。

示例:

编辑:

procedure TForm1.OnCreate(Sender: TObject);
  var list: TStringList;
begin
  list:=TStringList.Create;
  list.LoadFromFile('10MB_of_Data.txt');
  list.destroy;
end;

我怎么知道作为TStringList的“list”在内存中使用10 MB的空间?

谢谢。

2 个答案:

答案 0 :(得分:4)

我认为比较之前和之后的内存使用情况是一种方法,因为没有简单的方法可以看到事后的代码块分配了什么内存...例如,使用上面的字符串列表,类本身只会占用少量内存,因为它由指向其他分配(即字符串数组)的指针组成,而且它本身就是一个指向实际字符串的指针数组......这是一个相对简单的案例。

无论如何,这可以通过FastMM完成,其功能如下......

uses
  FastMM4;

function CheckAllocationBy(const AProc: TProc): NativeUInt;
var
  lOriginalAllocated: NativeUInt;
  lFinalAllocated: NativeUInt;
  lUsage: TMemoryManagerUsageSummary;
begin
  GetMemoryManagerUsageSummary(lUsage);
  lOriginalAllocated := lUsage.AllocatedBytes;
  try
    AProc;
  finally
    GetMemoryManagerUsageSummary(lUsage);
    lFinalAllocated := lUsage.AllocatedBytes;
  end;
  Result := lFinalAllocated - lOriginalAllocated;
end;

可以像这样使用......

lAllocatedBytes := CheckAllocationBy(
  procedure
  begin
    list:=TStringList.Create;
    list.LoadFromFile('10MB_of_Data.txt');
    list.Free;
  end);

这将告诉你你的字符串列表留下了多少(有趣的是我在第一次重复调用时得到40个字节,0之后在查询调用之前和之后的使用日志之后是在第一次打电话)。如果你想检查泄漏内存的分配位置,使用FastMM也很简单(虽然我同意上面的说法,如果它是第三方,那应该不是你的问题)。

答案 1 :(得分:1)

首先:请耐心等待,这实际上不是您的问题的答案,但是它太大了,无法在评论中发布。此代码是使用FPC编写和编译的,但它可以为您提供一些估算。可能有人知道如何将它移植到Delphi。

program project4;

uses
    SysUtils,
    Classes;

var
    p: Pointer;
    sl: TStringList;
var
    a: TFPCHeapStatus;
begin
    a := GetFPCHeapStatus;
    writeln('== 1 ==');
    //writeln(a.MaxHeapSize);
    writeln(a.MaxHeapUsed);
    //writeln(a.CurrHeapSize);
    writeln(a.CurrHeapUsed);
    //writeln(a.CurrHeapFree);

    GetMem(p, 1024);

    a := GetFPCHeapStatus;
    writeln('== 2 ==');
    writeln(a.MaxHeapUsed);
    writeln(a.CurrHeapUsed);

    sl := TStringList.Create;

    a := GetFPCHeapStatus;
    writeln('== 3 ==');
    writeln(a.MaxHeapUsed);
    writeln(a.CurrHeapUsed);

    sl.Add('To beer or not to beer? That is the question!');

    a := GetFPCHeapStatus;
    writeln('== 4 ==');
    writeln(a.MaxHeapUsed);
    writeln(a.CurrHeapUsed);

    Readln;
end.

并输出:

== 1 ==
2448
2448
== 2 ==
3488
3488
== 3 ==
3568
3568
== 4 ==
3616
3616

另一个带有大文本文件的测试:

sl.LoadFromFile('tolstoy - war and peace.txt');

a := GetFPCHeapStatus;
writeln('== 4 ==');
writeln(a.MaxHeapUsed);
writeln(a.CurrHeapUsed);  

输出:

== 3 ==
3568
3568
== 4 ==
8837104
4643776

文件大小:3,1 Mb(3 280 005字节)(ansi编码)