[英]Castle Windsor Interceptor memory leak
I ran into a problem where my program would run out of memory when using Castle Windsor and interceptors. 我遇到了一个问题,当使用Castle Windsor和拦截器时,我的程序会耗尽内存。 It's reproducible using the following code:
它可以使用以下代码重现:
public interface ITest{}
public class Test : ITest {}
class TestInterceptor:IInterceptor {
public void Intercept(IInvocation invocation) {}
}
class Program {
static void Main(string[] args) {
while(true) {
using(var container = new WindsorContainer()) {
container.Register(Component.For<TestInterceptor>());
container.Register(Component.
For<ITest>().
ImplementedBy<Test>().
Interceptors(
InterceptorReference.ForType<TestInterceptor>()
).Anywhere);
var tst = container.Resolve<ITest>();
}
}
}
}
This is how memory usage develops: 这就是内存使用的发展方式:
So the thing that threw me off was that I thought there was a non-managed code memory leak, but after a lot of debugging I found out the problem was with the interceptor prxoy generation: a new (dynamic) assembly with a proxy type is introduced to the runtime everytime it's resolved: 所以让我失望的是我认为有一个非托管代码内存泄漏,但经过大量调试我发现问题出在拦截器prxoy生成:一个带代理类型的新(动态)程序集是每次解决时都会引入运行时:
Now, I guess you can solve this by 现在,我想你可以解决这个问题
ProxyGenerator
and using the UsingFactoryMethod
way of producing an instance (which I do now) ProxyGenerator
自己生成代理并使用UsingFactoryMethod
生成实例的方式(我现在这样做) This leaves me to 3 questions: 这让我有3个问题:
Thank you. 谢谢。
I read this is the preferred way of doing this, not entirely clear why
我读过这是这样做的首选方式,并不完全清楚原因
Having one single container for the lifetime of the application is preferred, because: 在应用程序的生命周期内拥有一个容器是首选,因为:
I just ran into this same issue today. 我今天刚遇到同样的问题。 To answer #3 from the original post, the performance counter [.NET Clr Loading -> Current Assemblies] would have shown a linearly increasing number of assemblies when running your snippet of code due to the dynamic proxy types being loaded.
要回答原始帖子中的#3,由于加载了动态代理类型,性能计数器[.NET Clr加载 - >当前程序集]在运行代码片段时会显示线性增加的程序集数量。
Read the documentation carefuly. 仔细阅读文档 。 Make interceptors always transient.
使拦截器始终是瞬态的。
Correct code is: 正确的代码是:
public interface ITest{}
public class Test : ITest {}
class TestInterceptor:IInterceptor {
public void Intercept(IInvocation invocation) {}
}
class Program {
static void Main(string[] args) {
while(true) {
using(var container = new WindsorContainer()) {
container.Register(Component.For<TestInterceptor>().LifestyleTransient());
container.Register(Component.
For<ITest>().
ImplementedBy<Test>().
Interceptors(
InterceptorReference.ForType<TestInterceptor>()
).Anywhere);
var tst = container.Resolve<ITest>();
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.