2017-10-19 66 views
1

我是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,可能是第一個找到它的人。

回答

2

仔細查看您的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