【问题标题】:Ninject.MVC5 Release Scope Never Called - OutOfMemoryExceptionNinject.MVC5 发布范围从不调用 - OutOfMemoryException
【发布时间】:2018-04-01 01:48:01
【问题描述】:

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

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

所以我更进一步,将 OnePerRequestHttpModule.cs 的源代码从 GitHub 复制到我的项目中的一个新文件中,并将 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从未调用之后。

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

【问题讨论】:

    标签: ninject ninject.web.mvc


    【解决方案1】:

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

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

    This bug has been fixed in version 3.2.2

    【讨论】:

    • 哇,这在 2014 年已修复。当我安装 Ninject.MVC5 时,我安装了最新的非 beta 版本。我猜 NuGet 会自动提取 Ninject.Web.Common 和 Ninject.Web.Common.WebHost 的版本,这些版本在 Ninjuct.MVC5 3.2.1 存在之前就已经存在。这只是一个有根据的猜测,但这是我可以解释一周前安装并获得 2014 年版本的唯一方法。谢谢!
    猜你喜欢
    • 2011-12-17
    • 2018-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多