Как использовать файл дампа для диагностики утечки памяти?

У меня есть служба.NET с обычным рабочим набором около 80 МБ. Во время недавнего нагрузочного теста процесс достиг 3,5 ГБ памяти, из-за чего на всей машине было мало физической памяти (3,9 из 4 ГБ), и память не освобождалась долго после остановки нагрузочного теста. Используя диспетчер задач, я взял файл дампа процесса и открыл его в Visual Studio 2010 SP1, и я могу начать отладку на нем.

Как мне диагностировать проблему с памятью? У меня есть dotTrace Memory 3.x, поддерживает ли он профилирование памяти для файлов дампа? Если нет, помогут ли функции профилирования памяти в Visual Studio 2010 Premium (в настоящее время у меня есть Professional)? Может ли WinDbg помочь?

ОБНОВЛЕНИЕ: новая Visual Studio 2013 Ultimate теперь может напрямую диагностировать проблемы с памятью с помощью файлов дампа. Смотрите этот блог для более подробной информации.

4 ответа

Решение

Установите WinDbg. Вы должны убедиться, что вы получаете правильную версию x86 или x64 в зависимости от вашего дампа. Вот прямая ссылка на скачивание для x86.

На этом вы должны убедиться, что вы взяли правильный дамп. Вы можете использовать диспетчер задач для создания файла дампа (щелкните правой кнопкой мыши по процессу -> Создать файл дампа). Если вы используете 64-разрядную версию, а ваш процесс - x86, используйте 32-разрядную версию диспетчера задач (C:\Windows\SysWOW64\taskmgr.exe), чтобы получить файл дампа. См. Мою статью для получения дополнительной информации о получении файлов дампа, например, если вы используете XP и вам нужно использовать windbg для создания файла дампа.

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

Я предполагаю, что вы используете.NET4, если вы можете открыть дамп в Visual Studio. Вот очень краткое руководство, которое поможет вам работать с файлом dmp:

1) Запустите WinDbg, установите путь к символам (Файл -> Путь поиска символов) в

SRV*c:\symbols*http://msdl.microsoft.com/download/symbols

2) Откройте Crash dump или перетащите ваш файл.DMP на WinDbg.

3) введите это в командном окне

.loadby sos clr

(К вашему сведению, для.NET 2 команда должна быть .loadby sos mscorwks)

4) затем введите это

!dumpheap -stat

который перечисляет тип объектов и их количество. выглядит примерно так:

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

Есть еще много чего, Google - твой друг.

Обычно, если у вас есть утечка в управляемом приложении, это означает, что что-то не собирается. Общие источники включают

  • Обработчики событий: если подписчик не удален, издатель будет удерживать его.

  • статика

  • Финализаторы: заблокированный финализатор не позволит потоку финализатора запускать какие-либо другие финализаторы и, таким образом, предотвращает сбор этих экземпляров.

  • Точно так же заблокированная нить будет удерживать любые корни, которые она содержит. Конечно, если у вас есть заблокированные потоки, которые, вероятно, повлияют на приложение на нескольких уровнях.

Чтобы устранить это, необходимо проверить управляемую кучу. WinDbg + SOS (или PSSCOR) позволит вам сделать это. !dumpheap -stat Команда выводит список всей управляемой кучи.

Вы должны иметь представление о количестве экземпляров каждого типа, ожидаемых в куче. Как только вы найдете что-то странное, вы можете использовать !dumpheap -mt <METHOD TABLE> Команда для отображения всех экземпляров данного типа.

Следующим шагом является анализ корня этих экземпляров. Выберите один наугад и сделайте !gcroot на что. Это покажет, как этот конкретный экземпляр укоренен. Ищите обработчики событий и закрепленные объекты (обычно представляющие статические ссылки). Если вы видите там очередь финализатора, вам нужно проверить, что делает поток финализатора. Использовать !threads а также !clrstack Команды для этого.

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

Другие источники утечек включают: сборки, которые не выгружены, и фрагментацию кучи больших объектов. SOS/PSSCOR также может помочь вам найти их, но пока я пропущу детали.

Если вы хотите узнать больше, я рекомендую блог Тесс. Я также сделал пару видео, рассказывающих, как использовать WinDbg + SOS ( здесь и здесь).

Если у вас есть возможность отладки процесса во время его выполнения, я рекомендую использовать PSSCOR вместо SOS. PSSCOR - это, по сути, частная ветвь источников SOS, которая была дополнена дополнительными командами, а также улучшены многие из существующих команд SOS. Например, версия PSSCOR !dumpheap Команда имеет очень полезный дельта-столбец, который значительно облегчает устранение утечек памяти.

Чтобы использовать его, вам нужно запустить процесс, подключить WinDbg, загрузить PSSCOR и сделать !dumpheap -stat, Затем вы позволяете процессу запускаться снова, чтобы распределение было выполнено. Прервите выполнение и повторите команду. Теперь PSSCOR покажет вам количество экземпляров, которые были добавлены / удалены со времени предыдущей проверки.

Начиная с версии 2017.2 JetBrains dotMemory поддерживает анализ дампов памяти Windows со всем своим мощным и интересным графическим интерфейсом.

http://msdn.microsoft.com/en-us/library/ee817660.aspx

У Microsoft есть руководство здесь. Тем не менее, это слишком сложно для начинающих.

dotTrace может генерировать графики визуальной памяти (лучше, чем WinDbg), но никогда не использовать его для дампов.

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