4

デルファイの単一のコンポーネントによって使用されているメモリの量を取得することは可能ですか?

インターネットから単純な文字列をダウンロードしていますが、ダウンロードプロセスの終了までにメモリ使用量が最大ギガバイトになっていることがわかりますが、ダウンロードしたすべてのファイルを含む保存済みファイルを見ると、ファイルはキロバイト単位にすぎません。範囲、私がそれらを破壊したとしても、明らかにコンポーネントで何かが起こっています。

例:

編集:

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

TStringListとしての「リスト」がメモリ内で10MB相当のスペースを使用していることをどのように知ることができますか?

ありがとうございました。

4

2 に答える 2

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バイトを取得し、その後、呼び出しの前後の使用ログを調べた後、最初の呼び出しで2つのエンコーディングクラスが作成されます) 。リークされたメモリがどこに割り当てられたかを確認したい場合は、FastMMを使用してそれを行うのも簡単です(ただし、サードパーティの場合は問題にならないはずです)。

于 2013-03-26T08:54:18.403 に答える
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エンコーディング)

于 2013-03-25T21:18:00.283 に答える