C # EntityFramework IQueryable Утечка памяти - PullRequest
0 голосов
/ 10 октября 2018

Мы видим, что ресурсы памяти не освобождаются:

enter image description here

Со следующим кодом, использующим .NET Core:

class Program
{
    static void Main(string[] args)
    {
        while (true) {          
            var testRunner = new TestRunner();
            testRunner.RunTest();
        }
    }
}

public class TestRunner {
    public void RunTest() {
        using (var context = new EasyMwsContext()) {
            var result = context.FeedSubmissionEntries.Where(fse => TestPredicate(fse)).ToList();
        }
    }

    public bool TestPredicate(FeedSubmissionEntry e) {
        return e.AmazonRegion == AmazonRegion.Europe && e.MerchantId == "1234";
    }
}

Если я удаляю тестовый предикат .Where Я получаю прямую линию, как и ожидалось, с предикатом память будет продолжать расти бесконечно.

Поэтому, пока я могу решить проблему, я хотел бы понять, чтопроисходит

РЕДАКТИРОВАТЬ:

Изменение строки на:

public void RunTest() {
    using (var context = new EasyMwsContext()) {
        var result = context.FeedSubmissionEntries.ToList();
    }
}

Дает график: enter image description here

Так что я не верю, что это также связано с оценкой на стороне клиента?

EDIT 2:

Использование EF Core 2.1.4

И куча объектов: enter image description here

Редактировать 3:

Добавлен график хранения, кажется, проблема с EF Core?

enter image description here

Ответы [ 2 ]

0 голосов
/ 24 января 2019

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

Краткая сводка заключается в том, что при включении метода экземпляра в IQueryable онкэшируется, а методы не освобождаются даже после удаления вашего контекста.

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

  1. Перепишите ваши методы, чтобы методы экземпляра не включались в ваш IQueryable
  2. Преобразование IQueryable в список с помощью ToList () перед использованием методов LINQ, содержащих методы экземпляра (не идеально, если вы пытаетесь ограничить результаты запроса к базе данных)
  3. Сделать метод, который вы вызываете, статическимограничить, сколько памяти накапливается
0 голосов
/ 10 октября 2018

Я подозреваю, что виновником является не утечка памяти, а довольно неудачное дополнение к EF Core, Оценка клиента .Как и LINQ-to-SQL, при работе с лямбда / функцией, которую нельзя преобразовать в SQL, EF Core создаст более простой запрос, который читает more data и оценивает функцию на клиенте.

В вашем случае EF Core не может знать, что такое TestPredicate, поэтому прочитает каждую запись в памяти и попытается впоследствии отфильтровать данные.

BTW это то, что произошло , когда SO переместился в EF Core в прошлый четверг, 4 октября 2018 года. Вместо того, чтобы возвращать несколько десятков строк, запрос вернул ... 52 миллиона строк:

var answers = db.Posts
                .Where(p => grp.Select(g=>g.PostId).Contains(p.Id))
                ...
                .ToList();

Оценка клиентане является обязательным, но включен по умолчанию.EF Core регистрирует предупреждение каждый раз, когда выполняется оценка клиента, но это не поможет, если вы не настроили ведение журнала EF Core.

Безопасное решение - отключить оценку на стороне клиентакак показано в Необязательное поведение: генерировать исключение для клиентской оценки раздела документации, либо в методе OnConfiguring каждого контекста, либо глобально в конфигурации Startup.cs:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(...)
        .ConfigureWarnings(warnings => 
                           warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
}

ОБНОВЛЕНИЕ

Быстрый способ выяснить, что происходит, - это сделать два снимка памяти в окне диагностики и проверить, какие новые объекты были созданы и сколько памяти они используют.Вполне возможно, что в оценке клиента есть ошибка.

...