Ninject.MVC5版本范围从未调用 - OutOfMemoryException

时间:2017-10-19 22:25:18

标签: ninject ninject.web.mvc

我是Ninject的新手,但我已经确信Ninject.MVC5 NuGet包的开箱即用配置从未真正释放作用于HttpContext的对象。在我的一些较大的报告重复使用大量内存之后,我一直得到一个OutOfMemoryException。

为了证明我没有失去理智,我创建了一个空的测试项目。我在VS 2017中通过文件创建了一个默认项目 - >新项目 - > C# - >网络 - > ASP.NET Web应用程序 - > MVC(在模态中)。这也是一个新的解决方案,需要明确。然后我安装了Ninject 3.2.2(不是最新的; Ninject.MVC5需要< 3.3),然后安装了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发生得很清楚,这是预期b / c List对象必须增长的。但它继续攀升超过600MB,经过几十次刷新后,我的应用程序中出现OutOfMemoryException。

所以我更进了一步,将源代码从GitHub for 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处放置断点。每次调用请求A后,B 从不调用

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

1 个答案:

答案 0 :(得分:2)

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

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

This bug has been fixed in version 3.2.2