【问题标题】:Entity Framework - Disposed ObjectContext not collected by garbage实体框架 - 已处置的 ObjectContext 未被垃圾收集
【发布时间】:2011-12-29 04:41:04
【问题描述】:

正如标题所示,我最近在尝试追踪潜在的内存泄漏问题时发现,已处置的 objectcontext 似乎没有被垃圾收集。我在 Prism 和 MVVM 旁边的 WPF 应用程序中使用 EF 4。当我开始四处寻找解决方案时,我偶然发现了这篇文章: http://connect.microsoft.com/VisualStudio/feedback/details/666304/memory-leakage-issue-in-entity-framework

我所有的对象上下文都是在 using 块中使用的每个事务。我一直假设 objectcontext 将被处理并最终由 GC 收集。显然只有第一部分发生了(我正在使用 memprofiler)。有人可以指点我一个资源或让我知道一种让 GC 收集已处理的对象上下文的方法吗?

【问题讨论】:

    标签: entity-framework-4 memory-leaks


    【解决方案1】:

    垃圾收集和处置是内存管理的两个不同方面。

    Dispose 是您的类上的一种方法,您可以在其中手动释放资源。

    垃圾收集仅在 .NET 垃圾收集引擎决定运行时发生。通常建议您不要尝试修改此过程。垃圾收集器仅在某些启发式方法告诉它您的内存不足时才会运行,而在今天的硬件上可能永远不会运行(尤其是如果您在 64 位机器上)。

    如果你想玩强制收集,你可以使用:

    GC.Collect();
    

    在这里阅读更多:

    http://msdn.microsoft.com/en-us/library/xe0c2357.aspx

    【讨论】:

    • 我理解这些差异。无论如何,感谢您指出这一点。绝对回答了如何强制 GC 运行以收集已处理的 objectcontext 的问题。但本质上,我试图了解这是否是所有企业应用程序中的 EF 发生的情况,以及如何在他们的应用程序中管理内存。也许我应该这样表达这个问题。
    【解决方案2】:

    我发现这个调用序列对于强制 GC 运行很有用。

    GC.GetTotalMemory(false);
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    GC.GetTotalMemory(true);
    
    try
    {
        Process curProc = Process.GetCurrentProcess();
        curProc.MaxWorkingSet = curProc.MaxWorkingSet;
    }
    catch (Exception)
    {
    }
    

    但是,在阅读您链接的 Microsoft Connect 文章时,GC 未运行不是该用户的问题。该用户正在做的是在Session 中粘贴一个实体类,这是一个可怕的举动,并且将阻止父类由于答案中概述的原因(更改跟踪)而被处置。

    会话存储的对象应该是一个断开连接的类,而不是您从上下文中检索到的类。只要您不这样做,当您从对象上下文中检索到的任何内容的最后一个引用被释放时,您的对象上下文就会被释放。

    【讨论】:

    • 我的回答究竟是如何混淆 GC 和 Dispose 的?我正在回答他关于让 GC 启动的问题。我上面的回答已经把GC和Dispose的区别说清楚了,觉得没必要重复解释了。
    • 主要是你的最后一句话,你提到持有的“参考”正在阻止某些东西被处置。该术语通常用于表示对对象实例的“引用”将阻止 GC。说对某物的引用阻止它被处理似乎很奇怪,因为您实际上首先需要一个引用来调用Dispose(除了在终结器中调用它时)。但是,仔细阅读后,我不确定您的回答是否对此感到困惑。但后来的读者可能是。
    猜你喜欢
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    相关资源
    最近更新 更多