這是另一篇關於我繼承了一個IntraWeb應用程序,該應用程序有一個2MB的FastMM4報告的內存泄漏文本文件,其中我將它歸結爲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;
的類的第二實例也作爲被添加到一個TObjectList(未擁有),並與TObjectList破壞局部變量(FAdapters):
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;
的類的實例化第三是從TempMulticast.AddObserver觀察者模式的一部分(適配器)線abov即觀察員加入到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中的專用字段,但這會導致錯誤。
感謝,
保羅水稻
如果列表不包含它們,它們所在的列表是如何銷燬的? – 2009-06-27 15:53:09
FreeAndNil在其類的析構函數中的專用TObjectLists FCDSAdapters和FAdapter上調用。我放置了一些代碼,在FreeAndNil之前迭代調用每個TCwcBasicAdapter上的Remove,並且它們沒有任何區別,兩種方式都是TList.Delete。 – user122603 2009-06-28 12:47:28