4

我有一個ASP.NET MVC應用程序,它使用Castler Windsor IoC在每個Web請求的基礎上創建一個Linq2SQL datacontext。Linq to SQL DataContext Windsor IoC內存泄漏問題

由於某些原因,我不完全理解,每次創建新的數據上下文(在每個​​Web請求上)大約8K內存被佔用並且未釋放 - 這不可避免地導致OutOfMemory異常。

如果我強制垃圾收集內存釋放OK。

我DataContext類是非常簡單的:

public class DataContextAccessor : IDataContextAccessor 
{ 
    private readonly DataContext dataContext; 
    public DataContextAccessor(string connectionString) 
    { 
     dataContext = new DataContext(connectionString);   
    } 
    public DataContext DataContext { get { return dataContext; } } 
} 

溫莎國際奧委會webconfig實例化這個看起來像這樣:

<component id="DataContextAccessor" 
      service="DomainModel.Repositories.IDataContextAccessor, DomainModel" 
      type="DomainModel.Repositories.DataContextAccessor, DomainModel" 
      lifestyle="PerWebRequest">  
    <parameters> 
     <connectionString> 
     ... 
     </connectionString> 
    </parameters> 
    </component> 

有誰知道問題是什麼,以及如何解決它?

+1

參見:http://stackoverflow.com/questions/85183/windsor-container-how-to-force-dispose-of-an-object http://stackoverflow.com/questions/132940/why-does-城堡溫莎舉行,在瞬態對象 – 2009-11-11 00:40:27

回答

3

從我可以告訴,queen3是正確的,你的DataContextAccessor類需要實現IDisposable並從其.Dispose()方法調用datacontext.Dispose()。 (免責聲明:我還沒有和溫莎城堡的工作。)

或者,我會做的是把你的DataContextAccessorDataContextFactory,只創造了DataContext,當你調用一個方法(例如GetContext())。然後,你可以這樣做:

using(DataContext context = myDataContextFactory.GetContext()) { 
    // Do whatever you want with the context 
} 
// Context is disposed here 

你可能也想看看這個前面的問題:How do you reconcile IDisposable and IoC?

4

沒有你的DataContextAccessor並不需要實現IDisposable。溫莎非常聰明,無需對班級進行任何修改即可處理案件。

但是,正如在其他答案中指出DataContext確實實現了它,並且Windsor看到它並將其註冊爲清理(對其調用Dispose方法)。

你需要做的是打電話container.Release並傳遞你的根服務(這可能是DataContextAccessor你的情況)。溫莎然後將釋放它和它的所有依賴關係(它也將在DataContext上調用Dispose),並且內存將被釋放。

如果您使用的是ASP.NET MVC,請考慮使用MVCContrib項目,該項目具有處理組件釋放的Windsor集成功能。

1

我認爲@KrzysztofKoźmic是對的......你應該釋放你從溫莎得到的任何東西。

溫莎對任何習慣於IDisposable的人來說都是相當陌生的。這種明顯差異的原因在於組件生命週期的管理。如果從Windsor獲取IDisposable組件,則不知道該實例是否配置爲瞬態或單身(當然,這可能會隨着您的應用程序的發展而變化)。

如果你處置一個組件,它後來變成一個單身人士,其他一些客戶端代碼會想知道爲什麼它的組件突然失效!只有溫莎能夠爲您做出處置決定。

尼斯的博客帖子剋日什托夫(不會讓我張貼的鏈接!)

在我們的應用程序,我們已經取得了一切短暫的,除了幾個單身。瞬態似乎是最簡單的模式(只要每個人都明白你必須'釋放而不是處置')。如果你的測試中有一個模擬容器,你可以設置一個期望,你的模擬解決的每個組件都會調用Release,我也聽說瞬態比其他模式有更少的性能問題(??)?代碼當然更加便攜。最後但並非最不重要的一點,如果你有內存泄漏,並且你需要工作,爲什麼GC沒有收集什麼東西,請查看Tess Ferrandez的關於windbg的fab教程系列 http://blogs.msdn.com/b/tess/archive/2008/04/03/net-debugging-demos-lab-7-memory-leak-review.aspx ...罪魁禍首可能在某個地方出乎意料!