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 ...罪魁祸首可能在某个地方出乎意料!