介绍
我发现我的代码泄漏了TInterfacedObject
我作为接口引用保存的一个实例的内存。尽管我将引用变量重置为nil
使用后,但它仍然存在。
泄漏的对象是类TMasterObject
,它实现了两个接口IInterfaceX
和IInterfaceY
. 对象的引用保存在一个类型为 的变量中IInterfaceY
。
TMasterObject
的实施IInterfaceX
纯属巧合。因为它有两个实例TSomeObject
,需要引用这个接口,所以我也实现了它TMasterObject
。
MCVE/SSCCE
program InterfaceDependencies;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
IInterfaceX = interface end;
IInterfaceY = interface end;
TSomeObject = class(TObject)
FReference: IInterfaceX;
constructor Create(AReferenceX: IInterfaceX);
end;
TMasterObject = class(TInterfacedObject, IInterfaceX, IInterfaceY)
FObjectA: TSomeObject;
FObjectB: TSomeObject;
constructor Create;
destructor Destroy; override;
end;
{ TSomeObject }
constructor TSomeObject.Create(AReferenceX: IInterfaceX);
begin
FReference := AReferenceX;
end;
{ TMasterObject }
constructor TMasterObject.Create;
begin
FObjectA := TSomeObject.Create(Self); // increments "FRefCount" by 1
FObjectB := TSomeObject.Create(Self); // increments "FRefCount" by 1
end;
destructor TMasterObject.Destroy;
begin
FObjectA.Free;
FObjectB.Free;
inherited;
end;
var
LMasterObject: IInterfaceY;
begin
try
LMasterObject := TMasterObject.Create;
// 'TMasterObject(LMasterObject).FRefCount' is now "3" because of 'FObjectA.FReference' and 'FObjectB.FReference'
LMasterObject := nil; // decrements 'TMasterObject(LMasterObject).FRefCount' by 1
// 'LMasterObject' is not destroyed because 'TMasterObject(LMasterObject).FRefCount' is still "2"
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
问题
可以使用哪些策略
- 解决这个特定的问题和
- 以后避免此类问题?