Castle Windsor Typed Factory 无释放不泄漏
Castle Windsor Typed Factory without release does not leak
我正在使用 Castle Windsor Typed Factory。在我们的注册代码中,它被设置为可以创建一个 Transient 组件:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IThingFactory>().AsFactory());
container.Register(Component.For<IThing>().ImplementedBy<TransientObject>().Named("TransientObject").LifeStyle.Transient);
根据我对the Castle Windsor Typed Factory documentation I thought that a Transient object must be released by a Typed Factory method, otherwise the Typed Factory would keep a reference to the object. I tried to prove this by writing a test that used the method explained in this Whosebug article的理解。
但令我惊讶的是它实际上并没有失败,这意味着虽然我没有将瞬态对象释放回工厂,但它仍然可以被GC回收。我担心我的测试可能具有误导性,确实存在泄漏。
所以我的问题是:是我的 test 错了,还是 documentation 错了?
这是测试:
var factory = container.Resolve<IThingFactory>();
WeakReference reference = null;
new Action(() =>
{
var service = factory.GetTransientObject();
reference = new WeakReference(service, true);
})();
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.That(reference.Target, Is.Null, "reference should be null");
Windsor 跟踪 Transient
个实例,仅当它们有一些退役问题时。退役问题的典型示例是 class 实现了 IDisposable
接口。
所以,如果 IThing
是 Transient
并且它没有实现 IDisposable
和 那么它就没有任何其他退役问题Windsor 不会跟踪它,垃圾收集器 can/will 会删除 IThing
.
的实例
BUT(这是一个很大的但是),我建议你永远不要依赖这种行为。 IThing
可能会被开发人员更改,将来可能会变成一次性的。或者它可能会引起另一个退役问题。突然发生内存泄漏。因此,应遵循一个简单的规则:
任何时候通过调用 container.Resolve
显式解析对象时,都必须通过调用 container.Release
来释放它。同样,只要有类型的工厂显式创建对象,它就必须由有类型的工厂显式销毁。 对象是否为瞬态无关紧要,请注意其生命周期。总是。对象的创建者(无论是 windsor 还是类型工厂)负责对象的销毁。
基本上,@piotrwest 的评论是正确的。然而,这个答案旨在解释它不仅仅是关于 IDisposable
- 它是关于退役问题(IDisposable
只是其中之一)。
This great article 解释更多细节。
我正在使用 Castle Windsor Typed Factory。在我们的注册代码中,它被设置为可以创建一个 Transient 组件:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IThingFactory>().AsFactory());
container.Register(Component.For<IThing>().ImplementedBy<TransientObject>().Named("TransientObject").LifeStyle.Transient);
根据我对the Castle Windsor Typed Factory documentation I thought that a Transient object must be released by a Typed Factory method, otherwise the Typed Factory would keep a reference to the object. I tried to prove this by writing a test that used the method explained in this Whosebug article的理解。
但令我惊讶的是它实际上并没有失败,这意味着虽然我没有将瞬态对象释放回工厂,但它仍然可以被GC回收。我担心我的测试可能具有误导性,确实存在泄漏。
所以我的问题是:是我的 test 错了,还是 documentation 错了?
这是测试:
var factory = container.Resolve<IThingFactory>();
WeakReference reference = null;
new Action(() =>
{
var service = factory.GetTransientObject();
reference = new WeakReference(service, true);
})();
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.That(reference.Target, Is.Null, "reference should be null");
Windsor 跟踪 Transient
个实例,仅当它们有一些退役问题时。退役问题的典型示例是 class 实现了 IDisposable
接口。
所以,如果 IThing
是 Transient
并且它没有实现 IDisposable
和 那么它就没有任何其他退役问题Windsor 不会跟踪它,垃圾收集器 can/will 会删除 IThing
.
BUT(这是一个很大的但是),我建议你永远不要依赖这种行为。 IThing
可能会被开发人员更改,将来可能会变成一次性的。或者它可能会引起另一个退役问题。突然发生内存泄漏。因此,应遵循一个简单的规则:
任何时候通过调用 container.Resolve
显式解析对象时,都必须通过调用 container.Release
来释放它。同样,只要有类型的工厂显式创建对象,它就必须由有类型的工厂显式销毁。 对象是否为瞬态无关紧要,请注意其生命周期。总是。对象的创建者(无论是 windsor 还是类型工厂)负责对象的销毁。
基本上,@piotrwest 的评论是正确的。然而,这个答案旨在解释它不仅仅是关于 IDisposable
- 它是关于退役问题(IDisposable
只是其中之一)。
This great article 解释更多细节。