【问题标题】:Debuging memory leak VS2015. Massive native heap调试内存泄漏VS2015。海量原生堆
【发布时间】:2017-06-20 20:11:46
【问题描述】:

我正在努力解决我肯定可以看到的内存问题,但我不知道它究竟发生在何时何地。

我的托管堆大小似乎还可以(100MB),但本机堆大小在未知时刻开始增长,并且一直持续到大约 2GB 并且应用程序崩溃。

我的应用程序正在运行许多线程,并且它在许多循环中通过 EF 6 进行大量 Db 连接。 这就是为什么我很难仅通过查看日志或设置断点来调试代码。

我想也许我可以通过查看内存来了解问题所在,但只有我能看到的是我的本机堆大小主要由大小为 8,192 字节的对象填充。所以我可以看到这个问题确实发生了,但仍然不知道为什么。

我不确定我是否正在使用 Visual Studio 内存分析器的 100% 功能。
我现在可以看到的是:

我还能做些什么来找出问题?

也许这是个愚蠢的问题,但我正在研究这个问题两天,我几乎达到了我的想法极限。

我已经经历了断点、日志、代码分析,但我仍然没有任何线索。

如有任何想法,我将不胜感激。

[编辑] 2017/02/03 15:11

我能够找到导致泄漏的代码,但它对我来说仍然没有意义。这段代码怎么可能导致大量内存泄漏?

代码是:

public class DbData : IDisposable
{
    private DBEntity db;

    public DbData()
    {
        db = new FruitDBEntity();
    }

    public Fruit AddFruitDefinition(Fruit fruit)
    {
        lock (thisLock)
        {
            var newFruit = db.Fruits.Where(f => f.FruitId     == fruit.FruitId)
                                    .Where(f => f.FruitName   == fruit.FruitName)
                                    .Where(f => f.FruitColor  == fruit.FruitColor)
                                    .FirstOrDefault();
            if (newFruit == null)
            {
                newFruit = db.Fruits.Add(fruit);
                db.SaveChanges();
            }
            return newFruit;
        }
    }
}

每次我想使用方法AddFruitDefinition()时都会创建类DbData

using ( var data = new DbData() ) 
{
    data.AddFruitDefinition();
}

【问题讨论】:

  • 您可以尝试注释掉一些循环(如有必要,伪造数据)以尝试隔离导致问题的代码部分。也许你没有正确处理一些数据库对象......
  • 如果你知道 Debug Diag,它的泄漏跟踪功能可以很容易地分辨出哪个原生库对 Native 泄漏负责。
  • @RenéVogt :我能够找到该代码片段。但它看起来很正常。我不知道这里会出现什么问题。
  • 这只是一个猜测,因为我对 ef 没有经验:DbData.Dispose() 是否调用 db.Dispose()? (不确定它是否会改变任何东西,只是猜测)
  • 所以我没有想法,但请不要打电话给GC.Collect(),如果你将未发布的对象推到更高的阶段,这肯定会让事情变得更糟。

标签: c# entity-framework visual-studio memory-leaks


【解决方案1】:

首先,您需要至少两张快照。 据我所知(从图片中),您只拍了一张快照。

怎么办?

  1. 使用分析器启动应用程序。

  2. 执行常规步骤并拍摄快照。

  3. 重复您在第 2 步中执行的相同步骤,并拍摄另一个快照。
  4. 停止应用程序。您应该看到 2 个快照,单击 2ns 快照并选择与 #Snapshot 1 比较。 处理结果可能需要一些时间。
  5. 您应该能够在报告中看到一些额外的列(标识符、计数、大小、模块、计数差异。大小差异。 最后两列很重要。它们会告诉哪个类第二次使用更多/更少的内存。

总而言之...您需要找出内存泄漏的位置并修复它。您将通过比较快照来做到这一点。

【讨论】:

  • 谢谢!正如您所说,现在我可以检查这两个快照之间的差异,但不幸的是,我只将这些差异视为“未解决的分配”。没有任何参考。我找不到关于“未解决的分配”的任何信息。
猜你喜欢
  • 2010-12-01
  • 2021-01-10
  • 2010-11-23
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-28
相关资源
最近更新 更多