Linq to SQL DataContext Windsor IoC内存泄漏问题

发布于 2024-08-10 22:51:26 字数 1063 浏览 7 评论 0原文

我有一个 ASP.NET MVC 应用程序,它使用 Castler Windsor IoC 根据每个 Web 请求创建 Linq2SQL 数据上下文。

由于某些我不完全理解的原因,每次创建新的数据上下文(在每个​​ 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 webconfig 看起来像这样:

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

有谁知道问题是什么以及如何修复它?

I have an ASP.NET MVC app that creates a Linq2SQL datacontext on a per-web-request basis using Castler Windsor IoC.

For some reason that I do not fully understand, every time a new datacontext is created (on every web request) about 8k of memory is taken up and not released - which inevitably causes an OutOfMemory exception.

If I force garbage collection the memory is released OK.

My datacontext class is very simple:

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

The Windsor IoC webconfig to instantiate this looks like so:

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

Does anyone know what the problem is, and how to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

万人眼中万个我 2024-08-17 22:51:26

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

顺便提防 Windsor/IDisposable 问题:
http://www.jeremyskinner .co.uk/2008/05/03/aspnet-mvc-controllers-windsor-and-idisposable/
http://www.nablasoft.com/Alkampfer/?p=105

L2S DataContext implements IDisposable. Your interface also has to implement it, and call DataContext.Dispose(), so that Windsor knows that there're resources to be disposed.

By the way beware of Windsor/IDisposable problems:
http://www.jeremyskinner.co.uk/2008/05/03/aspnet-mvc-controllers-windsor-and-idisposable/
http://www.nablasoft.com/Alkampfer/?p=105

对不⑦ 2024-08-17 22:51:26

不,您的 DataContextAccessor 不需要实现 IDisposable。 Windsor 足够聪明,可以处理这种情况,而无需对您的类进行任何修改。

然而,正如其他答案中所述,DataContext 确实实现了它,并且 Windsor 看到了它,并将其注册以进行清理(以调用其上的 Dispose 方法)。

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

如果您使用 ASP.NET MVC,请考虑使用 MVCContrib 项目,该项目具有 Windsor 集成,可以为您处理组件的发布。

No your DataContextAccessor does not need to implement IDisposable. Windsor is smart enough to handle the case without having to do any modifications to your classes.

However since as noted in the other answers DataContext does implement it, and Windsor sees it and it registers it for cleanup (to call the Dispose method on it).

What you need to do is to call container.Release and pass your root service (which probably would be DataContextAccessor in your case). Windsor will then release it and all its dependencies (it will also call Dispose on DataContext) and the memory will be freed.

If you're using ASP.NET MVC consider using MVCContrib project which has Windsor integration that handles releasing of components for you.

梦一生花开无言 2024-08-17 22:51:26

据我所知, queen3 是正确的,您的 DataContextAccessor 类需要实现 IDisposable 并从其 .Dispose() 调用 datacontext.Dispose()代码>方法。 (免责声明:我没有使用过 Castle Windsor。)

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

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

你可能还想看看上一个问题: 如何协调 IDisposable 和 IoC?

From what I can tell, queen3 is correct, your DataContextAccessor class needs to implement IDisposable and call datacontext.Dispose() from its .Dispose() method. (Disclaimer: I haven't worked with Castle Windsor.)

Alternatively, what I would do is turn your DataContextAccessor into a DataContextFactory, which only creates the DataContext when you call a method (e.g. GetContext()). Then you can do this:

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

You might also want to take a look at this previous question: How do you reconcile IDisposable and IoC?

梦与时光遇 2024-08-17 22:51:26

我认为@Krzysztof Koźmic 是对的......你应该释放你从温莎得到的任何东西。

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

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

不错的博客文章 Krzysztof(不让我发布链接!)

在我们的应用程序中,除了几个单例之外,我们已经将所有内容都变成了瞬态。瞬态似乎是最简单的模型(只要每个人都明白你必须“释放而不是处置”)。如果您的测试中有一个模拟容器,您可以设置一个期望,即为您的模拟解析的每个组件调用 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 ...罪魁祸首可能是在意想不到的地方!

I think @Krzysztof Koźmic is right... you should release whatever you get from Windsor.

Windsor is pretty alien to anyone used to IDisposable. The reason for this apparent disparity is down to the management of the component's lifecycle. If you take a component from Windsor that is IDisposable, you don't know if that instance is configured as transient or a singleton (and of course this could change as your app evolves).

If you dispose a component and it later turns out to be a singleton, some other client code is going to be wondering why its component has suddenly failed!?! Only Windsor is able to make the Disposal decision for you.

Nice blog post Krzysztof (won't let me post link!)

In our app we've made everything transient, apart from a couple of singletons. Transient seems to be the simplest model (as long as everyone understands you must 'Release rather than Dispose'). If you have a mock container in your tests, you can set an expectation that Release is called for each component your mock resolves, and I've also heard that transient has fewer performance issues (??) than other modes? The code is certainly more portable.

Last but not least, if you have a memory leak and you need to work what and why something isn't being collected by the GC, check out Tess Ferrandez' fab tutorial series on windbg
http://blogs.msdn.com/b/tess/archive/2008/04/03/net-debugging-demos-lab-7-memory-leak-review.aspx ... the culprit may be somewhere unexpected!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文