我在Spring4d容器中注册了许多对象,有些是Singleton。当应用程序关闭时,几乎Singleton正确调用自己的销毁,但有些没有,FastMM报告内存泄漏。我正在寻找一种方法,如何记录哪些对象有问题。我尝试用这个简单的例子与容器扩展有经验:
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.
在注册中,我有
container.AddExtension<THCVLoggerExtension>;
集装箱正确调用THCVLoggerExtension.Initialize
,但在我的检查员从来没有被称为DoProcessModel
。为什么?
1条答案
按热度按时间8dtrkrch1#
可能是因为你在容器上调用
Build
之后添加了扩展?另一个原因可能是没有看到任何日志记录--你在DoProcessModel
中放置了一个断点来验证它没有被调用吗?到实际问题:单例的内存泄漏几乎总是由于容器没有计算出这些类的正确refcounting而导致的。当注册任何不是从
TInterfacedObject
继承的类时,将正确的TRefCounting
值传递给AsSingleton
。