Reputation: 2815
I found out my code leaks memory of an instance of a TInterfacedObject
that I keep as a Interface reference. Although I reset the reference variable to nil
after usage, it remains alive.
The leaked object is of class TMasterObject
, which implements two interfaces IInterfaceX
and IInterfaceY
. The object's reference is kept in a variable of type IInterfaceY
.
TMasterObject
's implementation of IInterfaceX
is merely coincidental. Because it has two instances of TSomeObject
, which requires a reference to this interface, I implemented it in TMasterObject
as well.
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.
What strategies can be used to
Upvotes: 1
Views: 149