Ninject.MVC5释放范围从未调用 - OutOfMemoryException

问题描述:

我是Ninject的新手,但我确信Ninject.MVC5 NuGet包的开箱即用配置从未实际释放作用域为HttpContext的对象。在我的一些较大的报告重复使用大量内存后,我一直得到OutOfMemoryException。Ninject.MVC5释放范围从未调用 - OutOfMemoryException

所以为了证明我没有失去理智,我创建了一个空的测试项目。我通过File - > New Project - > C# - > Web - > ASP.NET Web Application - > MVC(在模式中)在VS 2017中创建了一个默认项目。这也是一个新的解决方案,要清楚。然后我安装了Ninject 3.2.2(不是最新版本; < 3.3是Ninject.MVC5所必需的),然后安装了Ninject.MVC5。

然后我去HomeController.cs和第一添加一个类文件的底部:

public class MemoryEater : IDisposable 
{ 
    public List<int> _nums = new List<int>(); 

    public MemoryEater() 
    { 
     var rand = new Random(); // Use random so that I get a bit of CPU usage I can see in Task Manager 
     for (int cnt = 0; cnt < 2_500_000; ++cnt) 
     { 
      var key = rand.Next(); 
      _nums.Add(key); 
     } 
    } 

    public void Dispose() 
    { 
     if (_nums != null) 
      _nums = null; 
    } 
} 

然后我添加了一个构造函数来HomeController的:

public class HomeController : Controller 
{ 
    readonly MemoryEater _me; 

    public HomeController(MemoryEater me) 
    { 
     _me = me; 
    } 

最后我打开了NinjectWebCommon.cs,到目前为止我没有任何修改(该文件通过NuGet安装Ninject.MVC5创建为100%),并向RegisterServices添加了一行:

private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind<MemoryEater>().ToSelf().InRequestScope(); 
    }  

然后,我使用IISExpress运行应用程序并在Chrome(在Windows 10上)中查看。我刷新页面并观察内存使用率攀升;有些GC会随着内存使用量的下降而发生明显变化,这是List对象必须增长的预期目标。但它不断攀升至600MB以上,经过几十次刷新后,我的应用程序中出现OutOfMemoryException。

所以我去了一步,从GitHub复制的源OnePerRequestHttpModule.cs到我的项目一个新的文件,并分割方法DeactivateInstancesForCurrentHttpRequest,这样我可以把一个断点,其中ICache.Clear被称为:

public void DeactivateInstancesForCurrentHttpRequest() 
    { 
     if (this.ReleaseScopeAtRequestEnd) 
     { 
      var context = HttpContext.Current; 
      this.MapKernels(kernel => ClearCacheOfContext(kernel, context)); // BREAKPOINT A 
     } 
    } 

    private void ClearCacheOfContext(IKernel kernel, HttpContext context) 
    { 
     kernel.Components.Get<ICache>().Clear(context); // BREAKPOINT B 
    } 

我改变NinjectWebCommon用我的新OnePerRequestHttpModule的拷贝,并把在A和B断点每个请求被调用后,但B是从来没有所谓

我做错了什么或者这是一个合法的错误?对我来说这似乎是不可想象的,这个bug可能会存在,而我,Ninject的n00b,可能是第一个找到它的人。

仔细查看您的Ninject.Web.Common nuget软件包的版本。

如果它小于3.2.2,这是您的问题的原因。

This bug has been fixed in version 3.2.2

+0

哇,当我安装Ninject.MVC5我安装了最新的非测试版已修复在2014年。我猜NuGet会自动将Ninject.Web.Common和Ninject.Web.Common.WebHost的版本在Ninjuct.MVC5 3.2.1之前存在。这只是一个受过教育的猜测,但这是我能解释一周前安装并获得2014版本的唯一方法。Thx! – pbarranis