Измерение использования памяти в Visual Studio (C#, Visual Basic, C++, F#)
Найдите утечки памяти и неэффективную память при отладке с помощью средства диагностики использования памяти, интегрированного с отладчиком. Средство использования памяти позволяет принимать один или несколько моментальных снимков управляемых и собственных кучи памяти, чтобы понять влияние использования памяти типов объектов. Вы также можете анализировать использование памяти без подключения отладчика или нацеливаясь на работающее приложение. Дополнительные сведения см. в разделе Запуск средств профилирования в выпускных или отладочных версиях сборок. Сведения о выборе оптимального средства анализа памяти для ваших потребностей см. в статье Выбор средства анализа памяти.
Хотя вы можете собирать моментальные снимки памяти в любое время в средстве использования памяти, вы можете использовать отладчик Visual Studio для управления выполнением приложения при изучении проблем с производительностью. Настройка точек останова, пошаговой отладки, остановка всех процессов и других действий отладчика может помочь вам сосредоточиться на исследованиях производительности кода на наиболее важных путях выполнения. Выполнение этих действий во время работы приложения может исключить шум из кода, который не интересует вас, и может значительно сократить время, необходимое для диагностики проблемы.
Важный
Средства диагностики, интегрированные с отладчиком, поддерживаются для разработки .NET в Visual Studio, включая ASP.NET, ASP.NET Core, разработку машинного кода/C++ и приложения смешанного режима (.NET и собственные).
В этом руководстве описано следующее:
- Делайте моментальные снимки памяти
- Анализ данных об использовании памяти
Если использование памяти не предоставляет необходимые данные, другие средства в профилировщике производительности предоставляют различные типы сведений, которые могут оказаться для вас полезными. Во многих случаях узкое место в производительности вашего приложения может быть вызвано не памятью, а другими факторами, например процессором, отрисовкой пользовательского интерфейса или временем сетевого запроса.
Заметка
поддержка настраиваемого распределителя профилировщик памяти в собственном коде работает путем сбора данных о событиях, создаваемых во время выполнения событий ET W. Распределители в CRT и пакете SDK для Windows были аннотированы на исходном уровне, чтобы можно было записать их данные о выделении. Если вы пишете собственные распределители, то любые функции, возвращающие указатель на вновь выделенную память в куче, могут быть украшены с помощью __declspec(allocator), как показано в этом примере для myMalloc.
__declspec(allocator) void* myMalloc(size_t size)
Сбор данных об использовании памяти
Откройте проект, который необходимо отладить в Visual Studio, и установите точку останова в приложении в точке, в которой необходимо начать изучение использования памяти.
Если у вас есть область, в которой вы подозреваете проблему с памятью, установите первую точку останова перед тем, как возникнет проблема с памятью.
Совет
Поскольку может быть сложно зафиксировать профиль памяти операции, которая вас интересует, когда ваше приложение часто выделяет и освобождает память, задайте точки останова в начале и конце операции (или выполните пошаговое выполнение операции), чтобы найти точный момент изменения памяти.
Задайте вторую точку останова в конце функции или области кода, которую необходимо проанализировать (или после возникновения подозрительной проблемы с памятью).
Окно средств диагностики отображается автоматически, если вы не отключили его. Чтобы снова открыть окно, щелкните Отладка>Windows>Показать средства диагностики.
Выберите использование памяти с параметром Выбор инструментов на панели инструментов.
Щелкните Отладка / Запуск отладки (или Запустить на панели инструментов или F5).
Когда приложение завершит загрузку, появится представление сводки средств диагностики.
Заметка
Так как сбор данных памяти может повлиять на производительность отладки собственных или смешанных приложений, моментальные снимки памяти отключены по умолчанию. Чтобы включить моментальные снимки в собственных или смешанных приложениях, запустите сеанс отладки (сочетание клавиш: F5). Когда появится окно средств диагностики, перейдите на вкладку Использование памяти, а затем выберите Профилирование кучи.
Остановить (сочетания клавиш: Shift+F5) и перезапустить отладку.
Заметка
Поскольку сбор данных о памяти может повлиять на эффективность отладки собственных или смешанных приложений, моментальные снимки памяти изначально отключены по умолчанию. Чтобы включить моментальные снимки в нативных или смешанных приложениях, запустите сеанс отладки (сочетания клавиш: F5). Когда появится окно средств диагностики, выберите вкладку Использование памяти, а затем выберите Профилирование памяти.
Остановить (сочетания клавиш: Shift+F5) и перезапустить отладку.
Чтобы сделать снимок в начале сеанса отладки, выберите Сделать снимок на панели инструментов сводки использования памяти . (Это также может помочь установить здесь точку останова.)
Совет
Чтобы создать базовые показатели для сравнения памяти, рассмотрите возможность создания моментального снимка в начале сеанса отладки.
Запустите сценарий, который остановится на первой точке останова.
Пока отладчик приостановлен на первом брейкпойнте, нажмите Сделать снимок на панели инструментов сводки использования памяти.
Нажмите сочетание клавиш F5, чтобы запустить приложение до второй точки останова.
Теперь сделайте еще один моментальный снимок.
На этом этапе можно начать анализ данных.
Если у вас возникли проблемы с сбором или отображением данных, ознакомьтесь с устранение ошибок профилирования и устранение проблем.
Анализ данных об использовании памяти
Строки сводной таблицы использования памяти содержат моментальные снимки, сделанные во время сеанса отладки, и содержат ссылки на более подробные представления.
Имя столбца зависит от режима отладки, выбранного в свойствах проекта: .NET, нативный или смешанный (как .NET, так и нативный).
Столбец Объекты (Diff) (.NET) или Выделение памяти (Diff) (C++) отображает количество объектов в .NET или в нативной памяти на момент создания моментального снимка.
В столбце Размер кучи (Diff) отображается количество байтов в .NET и нативных кучах.
Когда вы делаете несколько моментальных снимков, ячейки сводной таблицы отображают изменение значения между текущим снимком строки и предыдущим снимком.
Чтобы проанализировать использование памяти, щелкните одну из ссылок, которые открывают подробный отчет об использовании памяти:
- Чтобы просмотреть сведения о разнице между текущим моментальным снимком и предыдущим, нажмите ссылку "Изменить" слева от стрелки (
). Красная стрелка указывает на увеличение использования памяти, а зеленая стрелка указывает на уменьшение.
Совет
Чтобы быстрее определить проблемы с памятью, отчеты диффа сортируются по типам объектов, которые увеличились в наибольшем общем количестве (щелкните ссылку на изменение в столбце Объектов (Diff)) или увеличились в наибольшем общем размере кучи (щелкните ссылку на изменение в столбце Размер Кучи (Diff)).
Чтобы просмотреть сведения только о выбранном моментальном снимке, щелкните ссылку для просмотра без изменений.
Отчет отображается в отдельном окне.
Отчеты по управляемым типам
Выберите текущую ссылку в ячейке объектов (Diff) в сводной таблице использования памяти.
Заметка
Для кода .NET значок просмотра экземпляров (типа объекта) доступен только при использовании средства анализа использования памяти , интегрированного в отладчик, или при открытии снимка кучи и выборе опции отладки управляемой памяти .
На верхней панели отображаются количество и размер типов в моментальном снимке, включая размер всех объектов, на которые указывает тип (общий размер).
В дереве путей к корню в нижней области отображаются объекты, ссылающиеся на тип, выбранный в верхней области. Сборщик мусора .NET очищает память для объекта только в том случае, если был выпущен последний тип, ссылающийся на него. Дополнительные сведения об использовании путей в корневом дереве см. в статье Анализ горячего пути к корневому.
В верхней панели показаны количество и размер типов снимка, включая размер всех объектов, на которые ссылается тип (включительный размер).
В нижней панели дерево "Пути к корню" отображает объекты, ссылающиеся на тип, выбранный в верхней панели. Сборщик мусора .NET очищает память для объекта только в том случае, если был выпущен последний тип, ссылающийся на него.
В дереве ссылочных типов отображаются ссылки, удерживаемые типом, выбранным в верхней области.
В дереве ссылочных типов отображаются ссылки, удерживаемые типом, выбранным в верхней области.
Чтобы отобразить экземпляры выбранного типа в верхней области, щелкните значок представления экземпляров рядом с типом объекта.
В представлении отображаются экземпляры выбранного объекта в моментальном снимке на верхней панели. В области Пути к корневому элементу и ссылочным объектам отображаются объекты, которые ссылаются на выбранный экземпляр, и типы, на которые ссылается выбранный экземпляр. Когда отладчик остановлен в точке, где был сделан снимок, вы можете навести указатель мыши на ячейку Значение, чтобы отобразить значения объекта в инструментальной подсказке.
В представлении экземпляры отображаются экземпляры выбранного объекта в моментальном снимке на верхней панели. В области пути к корневым и ссылочным объектам отображаются объекты, ссылающиеся на выбранный экземпляр и типы, ссылающиеся на выбранный экземпляр. Когда отладчик остановлен в месте, где был сделан снимок, вы можете навести указатель мыши на ячейку Значение, чтобы в подсказке появились значения объекта.
Отчеты встроенных типов
Выберите текущую ссылку ячейки выделений (Diff) или размера кучи (Diff) в сводной таблице использования памяти в окне средств диагностики .
В представлении типов отображается количество и размер типов в моментальном снимке.
Щелкните значок представления экземпляров рядом с выбранным типом, чтобы отобразить сведения об объектах выбранного типа в моментальном снимке.
В представлении экземпляров отображается каждый экземпляр выбранного типа. Выбор экземпляра отображает стек вызовов, который привёл к его созданию, в панели Стек вызовов выделения. (Эта информация доступна только во время отладки.)
Выберите значок экземпляров (
) выбранного типа, чтобы отобразить сведения об объектах выбранного типа в моментальном снимке.
В представлении экземпляров отображается каждый экземпляр выбранного типа. При выборе экземпляра отображается стек вызовов, приведший к его созданию, в панели Стек вызовов выделения.
В списке Режим просмотра выберите Представление стека, чтобы увидеть стек выделения для выбранного типа.
Аналитика использования памяти
Для управляемой памяти средство анализа памяти также предоставляет несколько мощных встроенных автоматических подробных сведений. Выберите вкладку Insights в отчетах управляемых типов, где отображаются применимые автоматические аналитики, такие как повторяющиеся строки, разреженные массивыи утечки обработчиков событий.
В разделе повторяющиеся строки отображается список строк, которые распределяются в куче несколько раз. Кроме того, в этом разделе показан общий объем пустой памяти, то есть (число экземпляров — 1) раз размер строки.
В разделе разреженных массивов показаны массивы, которые в основном заполнены нулевыми элементами, которые могут быть неэффективными с точки зрения производительности и использования памяти. Средство анализа памяти автоматически обнаруживает эти массивы и показывает, сколько памяти тратится из-за этих нулевых значений.
В разделе утечки обработчика событий, доступном в Visual Studio 2022 версии 17.9 ( предварительная версия 1), отображаются потенциальные утечки памяти, которые могут возникать, когда один объект подписывается на событие другого объекта. Если издатель события выходит из жизни подписчика, подписчик остается в живых, даже если к нему нет других ссылок. Это может привести к утечкам памяти, когда неиспользуемая память не освобождается должным образом, что приводит к тому, что приложение будет использовать больше и больше памяти с течением времени.
Некоторые типы, как известно, имеют поля, которые можно считывать для определения размера нативной памяти, удерживаемой ими. На вкладке аналитики , отображаются виртуальные узлы памяти в графе объектов, которые сохраняются родительскими объектами так, чтобы пользовательский интерфейс мог распознать их и отобразить их размер и граф ссылок.
Отчеты об изменениях (Diff)
Выберите ссылку на изменение в ячейке сводной таблицы на вкладке Использование памяти в окне Средства Диагностики.
Выберите моментальный снимок из списка сравнения с для управляемого или собственного отчета.
Отчет об изменениях добавляет столбцы (помеченные (Diff)) в базовый отчет, показывающие разницу между значением базового моментального снимка и моментальным снимком для сравнения. Вот как может выглядеть отчет различий представления собственного типа:
На верхней панели показаны количество и размер типов в снимке, включая полный размер всех объектов, на которые ссылается тип (инклюзивный размер).
Блоги и видео
Анализировать процессор и память при отладке
блог Visual C++: профилирование памяти в Visual C++ 2015
Дальнейшие действия
В этом руководстве вы узнали, как собирать и анализировать данные об использовании памяти. Если вы уже завершили тур профилировщика, вы можете ознакомиться с общим подходом к оптимизации кода с помощью средств профилирования.
В этом руководстве вы узнали, как собирать и анализировать данные об использовании памяти во время отладки. Вы можете узнать больше об анализе использования памяти в релизных сборках с помощью средства профилирования производительности.