这是另一篇关于我继承了一个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