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

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

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

UPDATE: Новая версия Visual Studio 2013 Ultimate теперь может диагностировать проблемы памяти с помощью файлов дампов. Подробнее см. этот пост в блоге.

Ответ 1

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

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

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

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

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

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

2) Откройте "Сброс" или перетащите файл .DMP на WinDbg.

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

.loadby sos clr

(FYI, для .NET 2 команда должна быть .loadby sos mscorwks)

4), введите этот

!dumpheap -stat

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

enter image description here

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

В windbg гораздо больше, google - ваш друг.

Ответ 2

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

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

  • Статика

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

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

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

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

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

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

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

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

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

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

Ответ 3

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

Ответ 4

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

В Microsoft есть руководство. Однако это слишком сложно для новичков.

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