Отладка утечки памяти VS2015. Массивная родная куча

Я борюсь с проблемой памяти, которую я точно вижу, но я не знаю, где и когда именно это происходит.

Кажется, мой размер управляемой кучи в порядке (100 МБ), но собственный размер кучи начинает увеличиваться в неизвестный момент и продолжает расти, пока не достигнет ~2 ГБ, а приложение не работает.

Мое приложение запускает много потоков, и оно выполняет много Db-соединения через EF 6 во многих циклах. Вот почему мне действительно сложно отлаживать код, просто просматривая логи или устанавливая точки останова.

Я подумал, может быть, я могу понять, в чем проблема, глядя на память, но я вижу только то, что мой собственный размер кучи в основном заполнен объектами размером 8192 байта. Итак, я вижу, что проблема действительно происходит, но до сих пор не знаю, почему.

Я не уверен, что я использую 100% возможности профилировщика памяти Visual Studio.
Теперь я вижу: Снимок родной кучи

Что еще или больше я могу сделать, чтобы найти проблему?

Может быть, это глупый вопрос, но я работаю над этой проблемой в течение двух дней, и я почти достиг предела своих идей.

Я прошел точки останова, журналы, анализ кода, но я до сих пор не знаю.

Буду благодарен за любую идею.

[EDIT] 15:11 2017/02/03

Я смог найти код, ответственный за утечку, но он все еще не имеет смысла для меня. Как это возможно, что этот код вызывает массовую утечку памяти?

Код является:

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;
        }
    }
}

Учебный класс DbData создается каждый раз, когда я хочу использовать метод AddFruitDefinition():

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

1 ответ

Во-первых, вам нужно как минимум два снимка. Насколько я вижу (из изображения) вы сделали только один снимок.

Что делать?

  1. Запустите приложение с помощью профилировщика.

  2. Делай обычные шаги и делай снимок.

  3. Повторите те же шаги, которые вы сделали в шаге 2, и сделайте еще один снимок.
  4. Остановить приложение. Вы должны увидеть 2 снимка, щелкнуть на снимке 2ns и выбрать "Сравнить с # снимком 1. Обработка результатов может занять некоторое время".
  5. Вы должны увидеть несколько дополнительных столбцов в отчете (Идентификатор, количество, Размер, Модуль, Разница по количеству. Разница по размеру. Последние два столбца важны. Они говорят, какой класс использовал больше / меньше памяти во второй раз.

Подводя итог... вам нужно выяснить, где утечка памяти и устранить ее. И вы сделаете это, сравнивая снимки.

Другие вопросы по тегам