Утечка памяти в .NET - увеличение пиков, затем возврат к базовому - PullRequest
0 голосов
/ 24 ноября 2018

У меня есть настоящий головной убор из-за утечки памяти при работе в Azure-app-service-webjob.

memory usage

Это фоновый рабочий процесс, считывающий работу из очереди и по расписанию.Примерно каждые 10 минут происходит увеличение использования памяти, прежде чем (примерно через 10 минут) вернуться к нормальному базовому уровню.Каждый шип немного выше каждый раз.До тех пор, пока, в конце концов, шип не достигнет достаточно высокого уровня (скажем,> 80%), после чего потребуется все больше и больше времени, чтобы вернуться к базовому уровню, и, наконец, он блокируется.Нет большого или большого количества запросов к базе данных, и ни одна из операций обработки не занимает больше нескольких секунд.Трудно получить очень четкий след, поскольку в 10-минутном цикле может быть 15-30 различных операций.

В любом случае.Некоторое время назад, когда он находился в фазе «максимума», я получил полный дамп памяти и подключил его к WinDbg.В памяти были миллионы сущностей Entity Framework (6) определенного типа, несмотря на то, что в базе данных было всего несколько тысяч.

Я не смог воспроизвести локально.Поэтому я добавил некоторый код в конструктор этого типа сущности - он хранит Dictionary<string,long> количества раз, которое определенный Environment.StackTrace виден из конструктора.Я жду, когда произойдет "максимизация", но при удаленном подключении на данный момент это выглядит довольно стандартно / нормально.

Учитывая, что эти объекты / могут / увеличиваться со временем, это необъясните растущие пики и вернитесь к исходному уровню.Так ли это?

Я также только что записал полный дамп памяти во время «базового уровня», а затем «небольшого всплеска» (всего несколько часов, как показано на рисунке).У меня есть элементарные навыки WinDbg.

В любом случае, мои вопросы / причины путаницы:

  1. Как определить разницу между двумя полными дампами памяти?
  2. Кто-нибудь видел что-то подобное раньше?
  3. Что может вызывать скачки памяти в каждом случае?
  4. Если это утечка памяти, почему она вообще возвращается к базовой линии между скачками?

IХотелось бы думать, что никакой магии не происходит, но я просто не могу найти вещь, которая совпадает со всплеском:

  • Количество записей в базе данных постепенно увеличивается, но составляет всего несколько тысяч,и проблема с памятью сбрасывается, если процесс перезапускается
  • Кажется, что ни одна операция не занимает более нескольких секунд, в соответствии с журналированием, несмотря на пики, продолжающиеся ~ 10 минут

1 Ответ

0 голосов
/ 24 ноября 2018

Как определить разницу между двумя полными дампами памяти?

Довольно сложно сделать в WinDbg.Это намного проще с инструментом анализа памяти, таким как Jetbrains dotMemory , который может импортировать необработанные дампы , если вы позаботились, используя правильный формат .

Кто-нибудь видел что-нибудь подобное раньше?

Да.

Что может вызывать рост шипов в памяти каждый раз?В памяти были миллионы сущностей Entity Framework (6) определенного типа, несмотря на то, что в базе данных было всего несколько тысяч.

Если у вас есть цикл O (n²), такой как

foreach(...)
    foreach(...)
        CreateAnObject();

, тогда 1000 строк в базе данных могут создать 1.000.000 объектов.Если вы просто добавите еще одну строку в базу данных, то в следующий раз при выполнении того же запроса будет еще 2001 объектов.

Если это утечка памяти, почему он когда-либо возвращается к базовой линии между пиками??

Я бы не назвал поведение скачка утечкой памяти.Это выглядит вполне нормально.Однако необходимо учитывать, что в какой-то момент времени ОЗУ становится недостаточно, и происходит переключение на жесткий диск.Ваше приложение становится намного медленнее.Возможно, вы можете изменить алгоритм.

Однако обратите внимание, что базовая линия не является постоянной:

baseline

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

Число записей базы данных постепенно увеличивается, но составляет всего несколько тысяч, и проблема с памятью сбрасывается, еслипроцесс перезапускается

Это может быть решено, если устранена утечка базиса.

Кажется, что ни одна операция не занимает больше, чем несколько секунд, по данным регистрации, несмотря на длительные пики~ 10 минут

Нет операции?Что за операция?Вызов метода?Как вы убедились, что вы измеряете все вызовы методов?В следующий раз, возможно, вы захотите добавить и график% процессора.

...