Измерение использования памяти в Visual Studio (C#, Visual Basic, C++, F#)

С помощью встроенного в отладчик средства диагностики Использование памяти вы сможете находить утечки памяти и выявлять ее неэффективное использование. С помощью средства "Использование памяти" можно сделать один или несколько снимков управляемой и собственной памяти в куче, чтобы понять влияние использования памяти типов объектов. Анализировать использование памяти также можно без подключения отладчика — нужно просто указать выполняющееся приложение. Дополнительные сведения см. в разделе Запуск средств профилирования с отладчиком или без него. Сведения о выборе необходимого средства анализа памяти см. в разделе Выбор инструмента для анализа памяти.

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

Важно!

Средства диагностики, интегрированные в отладчик, поддерживаются для разработки приложений .NET в Visual Studio, включая ASP.NET и ASP.NET Core, машинного кода или кода C++ и смешанных программ (на основе .NET и машинного кода). Для запуска средств профилирования с отладчиком (окно Средства диагностики) требуется Windows 8 и более поздние версии.

При работе с этим руководством вы сделаете следующее:

  • Создание моментальных снимков с данными об использовании памяти
  • Анализ данных использования памяти

Если средство Использование памяти не предоставляет необходимые данные, можно воспользоваться другими средствами профилирования в Профилировщике производительности, предоставляющими другие виды информации, которая может оказаться полезной. Как правило, проблемы производительности приложения могут вызываться другими компонентами помимо памяти, такими как ЦП, отрисовка пользовательского интерфейса или время запроса сети.

Примечание.

Поддержка пользовательского распределителя. Профилировщик внутренней памяти работает путем сбора данных событий ETW выделения памяти, создаваемых во время выполнения. Распределители в CRT и пакете Windows SDK аннотированы на уровне исходного кода, что позволяет регистрировать их данные выделения. Если вы создаете собственные распределители, любые функции, возвращающие указатель на только что выделенную память в куче, можно декорировать с использованием __declspec(allocator), как показано в этом примере для myMalloc:

__declspec(allocator) void* myMalloc(size_t size)

Сбор данных об использовании памяти

  1. Откройте проект для отладки в Visual Studio и установите точку останова в приложении в точке, где вы хотите начать проверку использования памяти.

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

    Совет

    Так как из-за изменений в объеме выделяемой памяти создание профиля памяти для интересующей вас операции может быть затруднительно, разместите точки останова в начале и в конце операции или пройдите по ней, чтобы попробовать найти точку, в которой объем памяти изменился.

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

  3. Окно Средства диагностики появится автоматически, если вы не отключали эту функцию. Чтобы снова открыть окно, щелкните Отладка>Окна>Показать средства диагностики.

  4. На панели инструментов выберите Использование памяти, применяя параметр Выбор средств.

    Screenshot of Diagnostics Tools.

    Screenshot of Diagnostics Tools.

  5. Щелкните Отладка | Начать отладку (Запустить на панели инструментов или F5).

    По завершении загрузки приложения отображается представление Сводка Средств диагностики.

    Screenshot of Diagnostics Tools Summary Tab.

    Примечание.

    Поскольку сбор данных об использовании памяти может повлиять на производительность отладки приложений, основанных на машинном коде, а также смешанных программ, по умолчанию снимки памяти выключены. Чтобы включить моментальные снимки для приложений на базе машинного кода или для смешанных программ, начните сеанс отладки (клавиша F5). Когда отобразится окно Средства диагностики, перейдите на вкладку Использование памяти и выберите Профилирование кучи.

    Screenshot of Enable snapshots.

    Остановите (сочетание клавиш: SHIFT+F5) и перезапустите отладку.

    Screenshot of Diagnostics Tools Summary Tab.

    Примечание.

    Поскольку сбор данных об использовании памяти может повлиять на производительность отладки приложений, основанных на машинном коде, а также смешанных программ, по умолчанию снимки памяти выключены. Чтобы включить моментальные снимки для приложений на базе машинного кода или для смешанных программ, начните сеанс отладки (клавиша F5). Когда отобразится окно Средства диагностики, перейдите на вкладку Использование памяти и выберите Профилирование кучи.

    Screenshot of Enable snapshots.

    Остановите (сочетание клавиш: SHIFT+F5) и перезапустите отладку.

  6. Чтобы сделать моментальный снимок в начале сеанса отладки, на сокращенной панели инструментов Использование памяти выберите команду Сделать снимок. (Таким образом здесь также можно задать точку останова.)

    Screenshot of Take Snapshot button.

    Screenshot of Take Snapshot button.

    Совет

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

  7. Запустите сценарий, который вызвал срабатывание первой точки останова.

  8. После приостановки отладчика на первой точке останова на сокращенной панели инструментов Использование памяти выберите команду Сделать снимок.

  9. Нажмите клавишу F5, чтобы запустить приложение до второй точки останова.

  10. Теперь создайте еще один моментальный снимок.

    На этом этапе можно начать анализировать данные.

    Если у вас возникли проблемы с сбором или отображением данных, см . статью "Устранение ошибок профилирования" и устранение проблем.

Анализ данных использования памяти

Строки сводной таблицы использования памяти содержат моментальные снимки, сделанные во время сеанса отладки, и содержат ссылки на более подробные представления.

Screenshot of Memory Usage table.

Screenshot of Memory Usage table.

Имя столбца зависит от режима отладки, выбранного в свойствах проекта: .NET, native или mixed (как .NET, так и в собственном коде).

  • В столбцах Объекты (разн.) и Выделения (разл.) указывается число объектов в .NET и внутренней памяти на момент создания моментального снимка.

  • В столбце Размер кучи (разн.) указывается число байтов в куче .NET и в собственных кучах.

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

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

  • Чтобы просмотреть сведения о разнице между текущим моментальным снимком и предыдущим моментальным снимком, выберите ссылку изменения слева от стрелки (Memory Usage Increase). Красная стрелка обозначает, что объем используемой памяти увеличился, а зеленая — что он снизился.

Совет

Чтобы быстрее выявить проблемы с памятью, типы объектов в отчетах об изменениях можно отсортировать по наибольшему увеличению общего объема (щелкните ссылку "Изменения" в столбце Объекты (разн.)) или по наибольшему увеличению размера кучи (щелкните ссылку "Изменения" в столбце Размер кучи (разн.)).

  • Чтобы отобразить подробности только для выбранного моментального снимка, щелкните ссылку "Без изменений".

    Отчет отображается в новом окне.

Отчеты об управляемых типах

Щелкните текущую ссылку в ячейке Объекты (разн.) или Выделения (разн.) в сводной таблице "Использование памяти".

Screenshot of managed type report.

Screenshot of managed type report.

В верхней области показываются число и размер типов, зарегистрированных снимком, включая размер всех объектов, на которые ссылаются типы (Инклюзивный размер).

В дереве Пути к корню в нижней области отображаются объекты, на которые ссылается тип, выбранный в верхней области. Сборщик мусора .NET очищает память для объекта только при освобождении последнего типа, ссылавшегося на него.

В дереве Объекты, на которые указывает ссылка отображаются ссылки, активные для выбранного в верхней области типа.

Screenshot of Referenced Objects report.

В дереве Типы, на которые указывает ссылка отображаются ссылки, активные для выбранного в верхней области типа.

Screenshot of Referenced Objects report.

Чтобы отобразить экземпляры типа, выбранного в верхней области, нажмите кнопку "Просмотреть экземпляры" рядом с типом объекта.

Screenshot of the Instances view in the Memory Usage tool.

Screenshot of the Instances view in the Memory Usage tool.

На панели Экземпляры , которая открывается в верхней области, отображаются экземпляры выбранного объекта текущего снимка. На панелях Пути к корню и Объекты, на которые указывает ссылка отображаются объекты, которые ссылаются на выбранный экземпляр, а также типы, на которые ссылается выбранный экземпляр. Если создать снимок после остановки отладчика и навести указатель мыши на ячейку в столбце Значение, во всплывающей подсказке отобразятся значения объекта.

Отчеты о собственных типах

Щелкните текущую ссылку в ячейке Выделения (разн.) или Размер кучи (разн.) в сводной таблице "Использование памяти", отображаемой в окне Средства диагностики.

Screenshot of Native Type View.

Screenshot of Native Type View.

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

  • Выберите значок экземпляров (The instance icon in the Object Type column) выбранного типа, чтобы отобразить сведения об объектах выбранного типа в моментальном снимке.

    В окне Экземпляры отображаются все экземпляры выбранного типа. При выборе экземпляра на панели Стек вызовов выделений отображается стек вызовов, использованный для создания этого экземпляра.

    Screenshot of the Instances view and Allocation Call Stack pane.

  • Чтобы отобразить информацию об объектах выбранного типа, зарегистрированных снимком, выберите Просмотреть экземпляры рядом с выбранным типом.

    В окне Экземпляры отображаются все экземпляры выбранного типа. При выборе экземпляра на панели Стек вызовов выделений отображается стек вызовов, использованный для создания этого экземпляра.

    Screenshot of the Instances view and Allocation Call Stack pane.

  • Чтобы отобразить стек вызовов для выбранного типа, в раскрывающемся меню Режим просмотра выберите пункт Представление стеков .

    Screenshot of Stacks view.

  • Чтобы отобразить стек выделений для выбранного типа, выберите Стеки.

    Screenshot of Stacks view.

Использование памяти Аналитика

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

Screenshot of the insight view in the Memory Usage tool.

В разделе "Повторяющиеся строки" отображается список строк, которые выделяются несколько раз в куче. Кроме того, в этом разделе показан общий объем пустой памяти, то есть (число экземпляров — 1) раз размер строки.

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

В разделе "Утечки обработчика событий", доступном в Visual Studio 2022 версии 17.9 ( предварительная версия 1), отображаются потенциальные утечки памяти, которые могут возникать, когда один объект подписывается на событие другого объекта. Если издатель события существует дольше подписчика, подписчик остается активным даже при отсутствии других ссылок на него. Это может привести к утечкам памяти, когда неиспользуемая память не освобождается должным образом. Это приводит к тому, что приложение будет использовать все больше и больше памяти с течением времени.

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

Screenshot of the native insight view in the Memory Usage tool.

Отчеты об изменениях

  • В окне Средства диагностики щелкните в необходимой ячейке сводной таблицы Использование памяти разницу в значениях.

    Screenshot of Choose a change link in a cell.

    Screenshot of Choose a change link in a cell.

  • Выберите моментальный снимок в списке Сравнить с , в котором отображаются управляемые или собственные отчеты.

    Screenshot of Choose a snapshot from the Compare To list.

    Screenshot of Choose a snapshot from the Compare with list.

С помощью отчета об изменениях в основной отчет можно добавить столбцы, помеченные надписью (Разн.), в которых будет отображаться разница между двумя выбранными снимками. Отчет об изменениях собственных типов может выглядеть следующим образом.

Screenshot of Native Types Diff View.

Screenshot of Native Types Diff View.

Блоги и видео

Анализ ресурсов ЦП и памяти во время отладки

Блог по Visual C++. Профилирование памяти в Visual C++ 2015

Следующие шаги

В этом руководстве вы узнали, как собирать и анализировать данные об использовании памяти. Если вы уже завершили обзор профилировщика, вам может потребоваться ознакомиться с общим подходом к оптимизации кода с помощью средств профилирования.

В этом руководстве вы узнали, как собирать и анализировать данные об использовании памяти во время отладки. Вы можете узнать больше об анализе использования памяти в сборках выпуска с помощью профилировщика производительности.