c# – 由于循环范围回调引用导致内存泄漏

c# – 由于循环范围回调引用导致内存泄漏,第1张

概述今天我们在生产中发生了重大中断,内存从我们的网络服务器中迅速消失.这可以追溯到Ninject中的缓存机制(我认为它是激活缓存或其他东西 – 不完全确定).在调查问题之后,我们得出结论,我们在范围回调中有一个循环引用. class View{ Presenter presenter; View() { //service locators are smel 今天我们在生产中发生了重大中断,内存从我们的网络服务器中迅速消失.这可以追溯到Ninject中的缓存机制(我认为它是激活缓存或其他东西 – 不完全确定).在调查问题之后,我们得出结论,我们在范围回调中有一个循环引用.
class VIEw{    Presenter presenter;    VIEw()    {        //service locators are smelly,but webforms forces this uglyness        this.presenter = ServiceLocator.Get<Func<VIEw,Presenter>>()(this);        this.presenter.InitUI();    }}class Presenter{    cookieContainer cookieContainer;    VIEw vIEw;    Presenter(VIEw vIEw,cookieContainer cookieContainer)    {        this.vIEw = vIEw;        this.cookieContainer = cookieContainer;    }}class cookieContainer{    httpRequest request;    httpResponse response;     cookieContainer()    {        this.request = httpRequest.Current.Request;        this.response = httpRequest.Current.Response;    }}Bind<Func<VIEw,Presenter>>().ToMethod(ctx => vIEw =>         ctx.Kernel.Get<Presenter>(new constructorargument("vIEw",vIEw)));Bind<Presenter>().ToSelf().InTransIEntScope();Bind<cookieContainer>().ToSelf().InRequestScope();

这是导致问题的代码的表示.看起来发生的事情是cookieContainer的范围回调是httpContext.Current,而cookieContainer也引用了httpContext.Current.所以Ninject永远不会从其缓存中删除cookieContainer实例,因为cookieContainer实例保持其范围回调对象的活动.当我们将cookieContainer的范围更改为瞬态时,一切正常,正如我们预期的那样.但是我仍然不能完全确定为什么会发生这种情况,因为看起来这是一个相当传统的做法呢?也许不是……

我也很困惑,因为我认为如果回调对象保持活着,那么Ninject不应该只从缓存中移回相同的实例,看到回调仍然存在,所以实例应该看起来像范围?为什么ninject会继续获取cookieContainer的新实例并缓存它们?我想还有其他与错误对象相关的问题,但这至少只是一个错误,而不是内存泄漏.

我的问题是a)我们是否正确诊断出此错误? b)是否有建议采取的方法不再发生这种情况? c)我可以修复代码以检查这种类型的循环依赖性(假设我们已经正确诊断了这个)?

解决方法 简单地说,缓存是实例的弱引用范围对象的字典.只要范围是活动的,引用的对象也会保持活动状态.所以,如果你的cookieContainer引用了httpContext.Current并且在请求范围内,那么这个标准机制永远不会适用于释放它们.

但在InRequestScope的特殊情况下,OnePerRequestModule实现了另一个释放机制,它将在请求完成后立即释放所有InRequestScoped对象.如果您使用的是Ninject.Web或Ninject.Web.MVC3的最新版本,则会预先配置它.否则,您必须通过在web.config中配置此httpModule来显式添加它.

你不明白的另一点是Ninject只要它存在就不会返回同一个对象.例如.在请求范围内,它将为请求返回相同的对象.如果多个请求同时运行,则它们都会获得不同的实例.

总结

以上是内存溢出为你收集整理的c# – 由于循环范围回调引用导致内存泄漏全部内容,希望文章能够帮你解决c# – 由于循环范围回调引用导致内存泄漏所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1244992.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存