Asp.net mvc Linq到SQL DataContext Windsor IoC内存泄漏问题

Asp.net mvc Linq到SQL DataContext Windsor IoC内存泄漏问题,asp.net-mvc,memory-leaks,inversion-of-control,castle-windsor,Asp.net Mvc,Memory Leaks,Inversion Of Control,Castle Windsor,我有一个ASP.NET MVC应用程序,它使用Castler Windsor IoC在每个web请求的基础上创建Linq2SQL数据上下文 由于某些我不完全理解的原因,每次创建一个新的datacontext(在每个web请求上),大约8k的内存被占用而没有释放,这不可避免地会导致OutOfMemory异常 如果我强制进行垃圾回收,内存释放正常 我的datacontext类非常简单: public class DataContextAccessor : IDataContextAccessor

我有一个ASP.NET MVC应用程序,它使用Castler Windsor IoC在每个web请求的基础上创建Linq2SQL数据上下文

由于某些我不完全理解的原因,每次创建一个新的datacontext(在每个web请求上),大约8k的内存被占用而没有释放,这不可避免地会导致OutOfMemory异常

如果我强制进行垃圾回收,内存释放正常

我的datacontext类非常简单:

 public class DataContextAccessor : IDataContextAccessor
 {
    private readonly DataContext dataContext;
    public DataContextAccessor(string connectionString)
    {
        dataContext = new DataContext(connectionString);           
    }
    public DataContext DataContext { get { return dataContext; } }
 }
用于实例化此功能的Windsor IoC网络配置如下所示:

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

...

有人知道问题是什么以及如何解决吗?

L2S DataContext实现IDisposable。您的接口还必须实现它,并调用DataContext.Dispose(),以便Windsor知道有需要处置的资源

顺便提一下,请注意温莎/IDisposable问题:

据我所知,您的
DataContextAccessor
类需要实现
IDisposable
并从其
.Dispose()
方法调用
datacontext.Dispose()
。(免责声明:我没有与温莎城堡合作过。)

或者,我要做的是将您的
DataContextAccessor
转换为
DataContextFactory
,它仅在调用方法时创建
DataContext
(例如
GetContext()
)。然后你可以这样做:

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

您可能还想看看前面的问题:

否您的
DataContextAccessor
不需要实现
IDisposable
。Windsor非常聪明,可以在不修改类的情况下处理这个问题

但是,正如其他答案中所指出的那样,DataContext确实实现了它,Windsor看到了它并将其注册以进行清理(对其调用
Dispose
方法)

您需要做的是调用
container.Release
并传递根服务(在您的情况下可能是
DataContextAccessor
)。Windsor随后将释放它及其所有依赖项(它还将调用
DataContext
上的
Dispose
),内存将被释放


如果你使用ASP.NET MVC,考虑使用MVCCONTIB项目,它有温莎积分来处理组件的发布。

< P>我认为克日什托夫KyMIC是正确的…你应该释放你从温莎得到的一切

温莎对于任何一个习惯于使用IDisposable的人来说都是相当陌生的。这种明显差异的原因在于组件生命周期的管理。如果您从Windsor获取一个IDisposable组件,您不知道该实例是配置为瞬态还是单例(当然,这可能会随着应用程序的发展而改变)

如果您处理了一个组件,但后来发现它是一个单例组件,那么其他一些客户机代码会想知道为什么它的组件突然出现故障!?!只有温莎能够为您做出处置决定

很好的博客帖子Krzysztof(不会让我发布链接!)

在我们的应用程序中,除了几个单件外,所有的东西都是暂时的。Transient似乎是最简单的模型(只要每个人都理解您必须“释放而不是处置”)。如果您的测试中有一个模拟容器,您可以设置一个期望,即为您的模拟解决的每个组件调用Release,并且我还听说transient比其他模式有更少的性能问题(??)?这段代码当然更便于移植

最后但并非最不重要的一点是,如果您有内存泄漏,您需要了解GC没有收集到什么以及为什么没有收集到某些内容,请查看Tess Ferrandez在windbg上的fab教程系列 ... 罪犯可能在某个意想不到的地方

见: