【问题标题】:EF DbContext memory not releasedEF DbContext 内存未释放
【发布时间】:2020-01-20 17:00:41
【问题描述】:

我无法释放 EF DbContext 使用的 proc 内存。 尽管有 dispose 和 GC.Collect,我的应用程序并没有释放内存。

我创建了一个小程序:

static void Main(string[] args)
{

    var test = new TestDb();
    System.Threading.Thread.Sleep(1000);

    // Here proc memory = 7 Mo

    test.Fill();
    System.Threading.Thread.Sleep(1000);

    // Here proc memory = 58 Mo

    test.Dispose();
    System.Threading.Thread.Sleep(1000);

    // Here proc memory = 37.8 Mo

    test = null;
    GC.Collect();

    // Here proc memory = 37.8 Mo
    // Why is not 0 here ???

    System.Threading.Thread.Sleep(1000);
}

您可以使用我的 cmets 显示内存使用情况。

TestDb 类:

 public class TestDb : IDisposable
{
    private List<TaskAction> _actions;

    public void Fill()
    {
        using (var entities = new myEntities())
        {
            entities.Configuration.LazyLoadingEnabled = false;
            _actions = entities.TaskActions.ToList();
        }
    }

    public void Dispose()
    {
        _actions = null;
        GC.Collect();
    }
}

如何释放所有使用的内存??

谢谢,

查理

【问题讨论】:

    标签: c# entity-framework memory garbage-collection


    【解决方案1】:

    如果我们只关注数据内存:除非有充分的理由,否则运行时不会将内存交还给操作系统;如果您刚刚使用了 {some amount of memory},那么您很有可能稍后会再次使用它,并且保持它要高效得多一阵子。 GC.Collect 只处理内部簿记,因此它不必在短期内向操作系统请求 更多 内存。您可以采取一些措施来使运行时在返回内存方面更具侵略性,但是...... 37Mb 基本上不算什么。

    此外,它仍然为内部 .NET 位(类型元数据、您已加载的所有程序集、JIT、IL 等)占用内存。使用 EF(或任何其他库)执行某事、任何事情会占用进程中的一些内存,不会被释放。既然您已经与数据库进行了交谈,那么现在可能还有一个连接池(托管和非托管),以及一些与 SQL 相关的线程。

    【讨论】:

    • 谢谢马克,这很有帮助。但是,如果有特定的请求会消耗大量内存怎么办?在我的例子中,使用 EFCore 数据创建一个 Excel 文件。构造的文件(在内存中)非常大。我想强制 .net 不缓存该内存。我试过GC.Collect,但没用。我已经使用&lt;ServerGarbageCollection&gt;false&lt;/ServerGarbageCollection&gt;
    • @Sean 在那句话中定义“缓存”; .net 没有一些神奇的缓存 API;如果一个对象是可访问的,那么它是不可收集的,所以如果您要说的是您希望对象可以更快地被收集:那么它们需要不可访问;如果不详细查看您的模型,这很难讨论;您可以尝试disabling tracking,并摆脱数据库上下文(即确保它无法访问),但是:除此之外:需要详细的上下文,我没有
    • (这可能不是讨论的地方,但是......)缓存可能是错误的词;我指的是您提到它将项目存储在内存中,以防它可能会在稍后再次使用。我可以在我的开发机器上看到这个特定的请求将内存增加了大约 500MB,并且不会很快释放。其中大部分很可能是使用 EPPlus 在内存中构建 XLSX 文档。 EPPlus 引用和 DBContext(+加载的数据)应该在请求之后被处理掉,但是其中一个或两个可能会保留。跟踪被禁用,因为它是只读访问。
    猜你喜欢
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 2019-04-02
    • 2015-06-21
    • 2012-05-22
    相关资源
    最近更新 更多