これは、FastMM4によって報告されたメモリリークの2MBのテキストファイルを持つIntrawebアプリケーションを継承した別の記事です。ここでは、1クラスの115インスタンスにそれぞれ52バイトのリークがあります。複数参照オブジェクトの解放
リークは、複雑なインスタンス化とクラスの処理からのものです。アプリをすぐに動作させるには、クラスの各インスタンス化が必要です。だから私は、クローンの単純なクリーンアップを使ってクラスをクローンするか、別の方法で参照するか、または..を参照するいくつかの方法を探しています。
クラス(TCwcBasicAdapter)の最初のインスタンスは、TObjectListを(所有せず)に加え、TObjectListを(FCDSAdapters)で破壊されますローカル変数の通りである:
procedure TCwcDeclaration.AttachAdapter(DS: TDataSource; const FormName, KeyFN, TitleFN: string; const Multiple: boolean = False;
const AllowAttachment: boolean = False; const AllowComment: boolean = False);
var
Forms : TCwcSessionForms;
Adapter: TCwcCDSAdapter;
KeyField, TitleField: TField;
begin
Forms := GetForms(FormName);
KeyField := DS.DataSet.FindField(KeyFN);
TitleField := DS.DataSet.FindField(TitleFN);
Adapter := TCwcBasicAdapter.Create(DS, KeyField, TitleField, Multiple);
Adapter.AttachDBPersist(Self.DBPersist);
Forms.AttachDataAdapter(Adapter);
Forms.SetAllowAttachments(AllowAttachment);
Forms.SetAllowComments(AllowComment);
end;
procedure TCwcSessionForms.AttachDataAdapter(aCDSAdapter: TCwcCDSAdapter);
var
Index: integer;
begin
if (FCDSAdapters.IndexOf(aCDSAdapter) -1)
then raise Exception.CreateFmt('Duplicate Adapter attempting to be attached on %0:s', [FFormClassName]);
Index := FCDSAdapters.Add(aCDSAdapter);
if (FDefaultAdapterIndex = -1)
then FDefaultAdapterIndex := Index;
end;
クラスの第二のインスタンスクラスの第三のインスタンスがTempMulticast.AddObserverからオブザーバーパターンの一部としてである
procedure TCwcCDSMulticastList.InitializeAdapters(const aSessionForms: TCwcSessionForms);
var
i, Count: integer;
Adapter: TCwcCDSAdapter;
TempMulticast: TCwcCDSEventMulticast;
begin
Count := aSessionForms.GetDataAdapterCount;
for i := 0 to Pred(Count) do begin
Adapter := aSessionForms.GetDataAdapter(i);
TempMulticast := FindDataSource(Adapter.DataSource);
if (TempMulticast = nil) then begin
TempMulticast := TCwcCDSEventMulticast.Create(Adapter.DataSource);
try
FMulticastList.Add(TempMulticast);
except
FreeAndNil(TempMulticast);
raise;
end;
end;
TempMulticast.AddObserver(Adapter);
FAdapters.Add(Adapter);
end;
end;
:TObjectListを(所有せず)に加え、TObjectListを(FAdapters)で破壊されますローカル変数としても(アダプタ)ラインabov e。オブザーバーは、(所有)TObjectListをFObserversに追加されます。
procedure TCwcCDSEventMulticast.AddObserver(const aCDSAdapter: TCwcCDSAdapter);
begin
FObservers.Add(TCwcCDSAdapterObserver.Create(aCDSAdapter));
end;
constructor TCwcCDSAdapterObserver.Create(const aCDSAdapter: TCwcCDSAdapter);
begin
inherited Create;
FOnStateChange := aCDSAdapter.OnStateChangeIntercept;
FOnAfterDelete := aCDSAdapter.AfterDeleteIntercept;
FInvalidateCursors := aCDSAdapter.InvalidateCursors;
end;
TCwcBasicAdapterはFObserversが破壊されたときにクリーンアップされません、ここに漏洩しています。
私が試した最新のことはFObserversを所有していないものに変更して、アダプタのプライベートフィールドを作成し、TCwcCDSAdapterObserver.Destroyのプライベートフィールドを解放していますが、エラーが発生します。
おかげで、
ポール・ライス
これらのオブジェクトは、リストが所有していない場合はどのように破壊されますか? –
FreeAndNilは、クラスのデストラクタのプライベートTObjectLists FCDSAdapterおよびFAdapterで呼び出されます。私はいくつかのコードを繰り返し、FreeAndNilの前に各TCwcBasicAdapterでRemoveを呼び出すと、それは何の違いもありませんでした。どちらの方法もTList.Deleteを実行します。 – user122603