FastMM は、次の行をメモリ リークの原因として報告します。
StrClassName := MidStr (curLine, length(START_OF_CLASSNAME)+1, length(curline)+1)
と はどうしたCopy
のMidStr
?これは Delphi 2007 コンパイラのバグだけですか、それともそれ以降のバージョンにもこの問題はありますか? ここに FastMM レポートのコピーへのリンクと、私のアプリケーションがこれらの種類のレポートを表示する方法の画像があります。ノードを表示するVirtualTreeView
には、新しいデータ型が必要です。私はそれを TMemoryLeak と呼んでいます。レポートを解析するときにTMemoryLeak
、クラス名、コールスタック、サイズなどを指定します。しかし、アプリがシャットダウンして FastMM が起動すると、上記のコピー行でメモリ リークが発生するようです。コールスタックのサイズ、オブジェクト全体の割り当てを解除しますが、文字列である ClassName フィールドは常にメモリをリークします。
更新(コメントから)
ここに宣言とコンストラクターとデコンストラクターがあります。寿命に関しては、オブジェクトがノードツリーを表示するために使用されるとすぐに、オブジェクトのデコンストラクターが呼び出されます。その後、それらは廃止され、割り当てが解除されます (希望します)。
TMemoryLeak = class(TObject)
private
fID :integer;
fSize :integer;
fTotalSize :integer;
fCallStack :TStringList;
fClassName :string;
fRepeatedInstance:integer;
public
property ID :integer read fID write fID;
property TotalSize :Integer read fTotalSize write fTotalSize;
property Size :integer read fSize write fSize;
property CallStack :TStringList read fCallStack write fCallStack;
property ClassName :string read fClassName write fClassName;
property RepeatedInstance :integer read fRepeatedInstance write fRepeatedInstance;
class function Equal(xA: TMemoryLeak; xB: TMemoryLeak): Boolean;
procedure clear;
constructor create;
destructor destroy; override;
end;
TMemoryLeakList=class(TObjectList)
private
fSortType :TMlSortType;
fSortDirection :TMLSortDirection;
fTotalLeakSize :integer;
fClassName :string;
fRepeatedInstance :Integer;
fID :Integer;
function GetItem(Index: Integer): TMemoryLeak;
procedure SetItem(Index: Integer; const Value: TMemoryLeak);
public
property Items[Index: Integer]:TMemoryLeak read GetItem write SetItem; default;
property TotalLeakSize :integer read fTotalLeakSize write fTotalLeakSize;
property SortType :TMLSortType read fSortType write fSortType;
property SortDirection :TMLSortDirection read fSortDirection write fSortDirection;
property ClassName :string read fClassName write fClassName;
property RepeatedInstance :integer read fRepeatedInstance write fRepeatedInstance;
property ID :Integer read fID write fID;
function Add(AObject: TMemoryLeak): Integer;
procedure Clear();
procedure Sort;
constructor create;
destructor destroy; override;
end;
constructor TMemoryLeak.create;
begin
inherited;
fCallStack := TStringList.create;
fRepeatedInstance:=0;
end;
destructor TMemoryLeak.destroy;
begin
clear;
end;
procedure TMemoryLeak.clear;
begin
fCallStack.Clear;
end;
class function TMemoryLeak.Equal(xA, xB: TMemoryLeak): Boolean;
var i:Integer;
begin
Result:=False;
if xA.ClassName = xb.ClassName then
begin
if xA.size = xb.size then
begin
if xA.CallStack.Count = xB.CallStack.Count then
begin
for i := 0 to xa.CallStack.Count - 1 do
begin
if CompareStr(xA.CallStack[i], xB.CallStack[i]) <> 0 then
begin
break;
end;
end;
if i = xa.CallStack.Count then
Result:=True;
end
end
end
end;
{ TMemoryLeakList }
constructor TMemoryLeakList.create;
begin
inherited;
fSortType :=stID;
fSortDirection :=sdAsc;
fClassName :='';
fRepeatedInstance :=0;
end;
destructor TMemoryLeakList.destroy;
begin
Clear;
end;
procedure TMemoryLeakList.Clear;
var i : Integer;
begin
for i := 0 to Count - 1 do
Items[i].clear;
end;