Эта статья относится к: ✔️ пакету SDK для .NET Core 3.1 и более поздних версий
Память может утечь, когда приложение ссылается на объекты, которые больше не требуется выполнять нужную задачу. Ссылка на эти объекты предотвращает восстановление используемой памяти сборщиком мусора. Это может привести к снижению производительности и возникновению OutOfMemoryException исключения.
В этом руководстве показаны средства для анализа утечки памяти в приложении .NET с помощью средств командной строки .NET диагностика. Если вы находитесь в Windows, вы можете использовать средства диагностики памяти Visual Studio для отладки утечки памяти.
В этом руководстве используется пример приложения, которое намеренно утечки памяти в качестве упражнения. Вы также можете анализировать приложения, которые непреднамеренно утечки памяти.
При работе с этим руководством вы сделаете следующее:
Изучение использования управляемой памяти с помощью dotnet-counters.
Создание файла дампа.
Анализ использования памяти с помощью файла дампа.
В этом руководстве предполагается, что примеры приложений и инструментов установлены и готовы к использованию.
Изучение использования управляемой памяти
Прежде чем приступить к сбору диагностических данных, чтобы помочь в первопричине этого сценария, убедитесь, что вы на самом деле видите утечку памяти (рост использования памяти). Для этого используйте dotnet-counters.
Откройте окно консоли и перейдите к каталогу, в который вы скачали и распаковали пример целевого объекта отладки. Запустите целевой объект:
dotnet run
В отдельном окне консоли найдите идентификатор процесса:
Теперь проверьте использование управляемой памяти с помощью инструмента dotnet-counters. --refresh-interval задает время между обновлениями (в секундах):
Динамические выходные данные должны выглядеть следующим образом:
Press p to pause, r to resume, q to quit.
Status: Running
[System.Runtime]
# of Assemblies Loaded 118
% Time in GC (since last GC) 0
Allocation Rate (Bytes / sec) 37,896
CPU Usage (%) 0
Exceptions / sec 0
GC Heap Size (MB) 4
Gen 0 GC / sec 0
Gen 0 Size (B) 0
Gen 1 GC / sec 0
Gen 1 Size (B) 0
Gen 2 GC / sec 0
Gen 2 Size (B) 0
LOH Size (B) 0
Monitor Lock Contention Count / sec 0
Number of Active Timers 1
ThreadPool Completed Work Items / sec 10
ThreadPool Queue Length 0
ThreadPool Threads Count 1
Working Set (MB) 83
Рассмотрите подробнее эту строку:
GC Heap Size (MB) 4
Как видите, сразу после запуска объем управляемой динамической памяти составляет 4 МБ.
Теперь перейдите по URL-адресу https://localhost:5001/api/diagscenario/memleak/20000.
Обратите внимание, что объем использования памяти увеличился до 30 МБ.
GC Heap Size (MB) 30
Просмотрев данные об использовании памяти, вы можете точно определить, что происходит: утечка или увеличение памяти. Следующим шагом является сбор правильных данных для анализа памяти.
Создание дампа памяти
При анализе возможных утечек памяти необходимо получить доступ к куче памяти приложения для анализа содержимого памяти. Глядя на связи между объектами, вы создаете теории о том, почему память не освобождается. Распространенный источник диагностических данных — это дамп памяти в Windows или эквивалентный основной дамп в Linux. Для создания дампа приложения .NET можно использовать средство dotnet-dump .
Выполните приведенную ниже команду, чтобы создать основной дамп в Linux для предварительно запущенного примера целевого объекта отладки:
dotnet-dump collect -p 4807
В результате в той же папке будет создан основной дамп.
Writing minidump with heap to ./core_20190430_185145
Complete
Примечание
Для сравнения с течением времени позвольте исходному процессу продолжить работу после сбора первого дампа и сбора второго дампа таким же образом. Затем у вас будет два дампа за период времени, который можно сравнить, чтобы увидеть, где растет потребление памяти.
Перезапуск неисправного процесса
После сбора дампа у вас должно быть достаточно данных для диагностики неисправного процесса. Если неисправный процесс запущен на рабочем сервере, это удачный момент для выполнения краткосрочного исправления проблем путем перезапуска процесса.
Вы уже завершили работу с примером целевого объекта отладки в рамках этого учебника и можете закрыть этот объект. Перейдите к терминалу, с которого запущен сервер, и нажмите клавиши CTRL+C.
Анализ основного дампа
Теперь, когда у вас есть основной дамп, используйте инструмент dotnet-dump, чтобы проанализировать его:
dotnet-dump analyze core_20190430_185145
Где core_20190430_185145 — это имя основного дампа, который нужно проанализировать.
Примечание
Если отображается сообщение о том, что libdl.so не удалось найти, возможно, потребуется установить пакет libc6-dev. Дополнительные сведения см. в разделе "Предварительные требования для .NET" в Linux.
Появится запрос, в котором можно ввести команды SOS . Как правило, в первую очередь нужно просмотреть общее состояние управляемой динамической памяти:
Как видно, String непосредственно содержится в объекте Customer и косвенно в объекте CustomerCache.
Вы можете продолжить разгрузку объектов и увидите, что большинство объектов String следуют той же модели. На этом этапе в результате исследования получено достаточно информации, чтобы найти основную причину утечки в коде.
Эта общая процедура позволяет определить источник основных утечек памяти.
Очистка ресурсов
В этом учебнике вы запустили пример веб-сервера. Работа этого сервера должна быть завершена, как описано в разделе Перезапуск неисправного процесса.
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Отзыв о .NET
.NET — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Использование Web App Down, Crash Monitoring и Ask Genie для устранения неполадок. Используйте эти средства для мониторинга доступности приложений и платформ, выявления необработанных исключений, записи дампов памяти и стека вызовов, а также поиска областей для исследования и диагностики.