I have many objects registered in Spring4d container,some as Singleton.When Application shutdown almost Singletons correct call own Destroy,but some no and FastMM reports Memory leaks. I'm looking for a way,how Log which objects have problem. I try experienced with Container Extension with this simple example:
unit Spring.Container.HCV.Extension;
interface
uses
Spring.Container.Extensions, Spring.Container.Core, Spring.Container.Builder;
type
THCVLoggerBuilderInspector = class(TInspectorBase)
protected
procedure DoProcessModel(const kernel: IKernel; const model: TComponentModel); override;
end;
TFakeBuilderInspector = class(TInspectorBase)
protected
procedure DoProcessModel(const kernel: IKernel; const model: TComponentModel);
override;
end;
THCVLoggerExtension = class(TContainerExtension)
protected
procedure Initialize; override;
end;
implementation
uses
Spring.Container.Common;
procedure THCVLoggerBuilderInspector.DoProcessModel(const kernel: IKernel;
const model: TComponentModel);
var
lLT:string;
begin
if model.ComponentType.IsInstance then
begin
case model.LifetimeType of
TLifetimeType.Unknown: lLT:='Unknown ';
TLifetimeType.Singleton: lLT:='Singleton ';
TLifetimeType.Transient: lLT:='Transient ';
TLifetimeType.PerResolve: lLT:='PerResolve ';
TLifetimeType.SingletonPerThread: lLT:='SingletonPerThread';
TLifetimeType.Pooled: lLT:='Pooled ';
TLifetimeType.Custom: lLT:='Custom ';
else
end;
kernel.Logger.Info('Builder: [%s] %s',[lLT,model.ComponentTypeName]);
end;
end;
procedure THCVLoggerExtension.Initialize;
begin
Kernel.Builder.AddInspector(THCVLoggerBuilderInspector.Create);
Kernel.Builder.AddInspector(TFakeBuilderInspector.Create);
end;
procedure TFakeBuilderInspector.DoProcessModel(const kernel: IKernel; const
model: TComponentModel);
begin
kernel.Logger.Info('FakeBuilderInspector');
end;
end.
In Registration I have
container.AddExtension<THCVLoggerExtension>;
Container correct call THCVLoggerExtension.Initialize
but in my inspectors is never called DoProcessModel
.Why?
CodePudding user response:
Possibly because you added the extension after you called Build
on the container? Another reason could be simply not seeing any logging - did you place a breakpoint in the DoProcessModel
to verify it's not called?
To the actual problem: Memory leaks with singletons are almost always a result of the container not figuring out the correct refcounting of those classes. Pass the correct TRefCounting
value to AsSingleton
when registering any classes that are not inherited from TInterfacedObject
.