Как найти причину «тормозов» с PerfView и dotnet-trace — практика анализа производительности .NET
· Обновлено: · Го Комура · PerfView, dotnet-trace, ETW, Анализ производительности, .NET, CSharp, Расследование сбоев, Разработка под Windows, Технический консалтинг
История изменений (1 обновлений, последнее 30 Aug 2026)
Журнал изменений этой статьи. Там, где версия до правки была заархивирована, она остаётся доступной для чтения по постоянной ссылке с DOI.
- Русский текст переписан как полноценный технический перевод, а не калька с японского. Утверждения статьи не менялись.
- Первая публикация
Цитирование статьи(DOI (зарегистрированный архив): 10.5281/zenodo.21620004)
Приведённые ниже DOI относятся к ранее зарегистрированным архивным версиям, которые могут отличаться от текущего текста. Для ссылки на текущий текст используйте URL этой страницы.
Го Комура (2026). Как найти причину «тормозов» с PerfView и dotnet-trace — практика анализа производительности .NET. KomuraSoft LLC. https://comcomponent.com/ru/blog/perfview-dotnet-trace-performance-analysis/
- DOI (зарегистрированный архив)
- 10.5281/zenodo.21620004
- DOI (последняя зарегистрированная версия)
- 10.5281/zenodo.21620005
В предыдущей статье «Журнал событий Windows и ETW» разбиралось, что такое ETW и как через EventSource задать свои события; разбор в PerfView там был вынесен «за рамки». Эта статья — продолжение. Она показывает, как с помощью PerfView и dotnet-trace дойти до конкретной функции, когда бизнес-приложение «тормозит», «ЦП постоянно на максимуме» или «иногда зависает».
Тема статьи — ЦП и время отклика. Как отличить рост памяти от утечки — в «.NET: как отличить ожидание GC от утечки памяти», аварийные завершения — в «Как читать аварийные дампы в WinDbg + SOS».
1. Сначала выводы
- «Тормоза» бывают двух видов: ЦП загружен полностью (CPU-bound) или ЦП свободен, но поток чего-то ждёт (блокировка). Для первого нужно сэмплирование ЦП, для второго — сбор ThreadTime (переключения контекста). Обычный сбор ЦП причину второго не покажет.1
- Если сомневаетесь, начните с dotnet-trace. Это кроссплатформенный инструмент на базе EventPipe: если вы тот же пользователь, от которого запущен целевой процесс, собрать трассу можно без прав администратора.2 Файл
.nettraceоткрывается в PerfView или Visual Studio.3 - PerfView нужен, когда требуется картина по всей машине, нативный код или время блокировки. В основе — ETW, поэтому видны события ядра и нативные стеки. Зато для старта сеанса ETW нужны права администратора.3
- Сэмплирование ЦП по умолчанию идёт раз в миллисекунду (на процессор). Читайте одну выборку как примерно 1 мс времени ЦП и не делайте выводов, пока не наберётся не меньше 1000 выборок, лучше около 5000. Пока выборок мало, функции наверху списка могут оказаться случайностью.1
- Интерпретация цифр всегда начинается с inclusive (сама функция плюс всё, что она вызвала) и exclusive (только сама функция). Большое exclusive — место, которое реально потребляет ЦП. Большое inclusive — признак, что тяжесть сидит где-то ниже по дереву вызовов.
- До сбора сведите «медленно» к одной конкретной операции. Снимать трассу на фоне «в целом тяжело» почти бесполезно. Сначала закрепите действие и длительность — например, «этот отчёт формируется 40 секунд» — и только потом собирайте. Как сравнивать до и после, разобрано в «Как правильно сравнивать скорость разных версий программы в Windows».
Вход по симптому — в таблице.
| Симптом | С чего начать | На что смотреть |
|---|---|---|
| ЦП постоянно на максимуме | dotnet-trace collect / CPU Stacks в PerfView | функции с большим exclusive |
| ЦП свободен, но обработка медленная или зависает | PerfView (сбор ThreadTime) | какой поток заблокирован и чего ждёт |
| Медленно, но сначала нужна общая картина | dotnet-counters | загрузка ЦП, частота GC, рост очереди ThreadPool |
| Подозрение, что GC слишком частый | dotnet-counters → dotnet-trace (события GC) | число и длительность пауз GC, где больше всего выделений |
| Нужно найти, где тормозит конкретная бизнес-операция | свои события EventSource + инструменты выше | время между своими событиями и стек на этом интервале |
На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 20, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle
2. Связь инструментов — ETW и EventPipe
Инструментов кажется много, но опорных механизмов два.
- ETW (Event Tracing for Windows): инфраструктура трассировки на всю ОС. Ядро и приложение пишутся на одной шкале времени, зато старт и останов сеанса требуют прав администратора, и это только Windows.3
- EventPipe: механизм трассировки внутри runtime .NET. Права администратора не нужны, на всех ОС ведёт себя одинаково. Видно только управляемый код и runtime: события ядра и нативные стеки он не снимает.2
| dotnet-trace (EventPipe) | PerfView (ETW) | |
|---|---|---|
| Права администратора | Не нужны (для процесса того же пользователя) | Нужны |
| Цель | Один указанный .NET-процесс | Вся машина (все процессы + ядро) |
| Нативные стеки | Нет | Есть |
| Время блокировки (переключения контекста) | Нет | Есть при сборе ThreadTime |
| ОС | Windows / Linux / macOS | Только Windows |
Когда эта карта ясна, рабочий порядок складывается сам: сначала лёгкий сбор через dotnet-trace, а если его не хватает — полный ETW-сбор в PerfView.
3. Перед сбором трассы — 10 минут на dotnet-counters
Сразу снимать трассу чаще всего рано: быстрее сначала посмотреть основные метрики runtime через dotnet-counters.4
dotnet tool install --global dotnet-counters
dotnet-counters ps
dotnet-counters monitor --process-id <PID> --counters System.Runtime
Смотрите загрузку ЦП, размер кучи GC и число сборок, длину очереди и число потоков ThreadPool, число исключений. Уже на этом шаге тенденции вроде «GC запускается несколько раз в секунду» или «очередь ThreadPool всё растёт» подсказывают, какую трассу снимать дальше — на выделения или на блокировки.
Но тому, кто измеряет впервые, не видно, «аномально это или нет». Самый надёжный ориентир — те же команды на своём приложении в нормальном режиме. Пока такой базы нет, ниже — практический взгляд на цифры как первое приближение.5
Счётчик (System.Runtime) |
Как читать | Подозрительный знак |
|---|---|---|
| CPU Usage (%) | Загрузка ЦП всего процесса | Держится на величине одного ядра (на 4 ядрах ≈ 25%) и не сдвигается = один поток крутится без остановки |
| GC Heap Size (MB) | Размер управляемой кучи | После окончания обработки не падает и монотонно растёт = подозрение на утечку |
| Gen 0 GC Count | Число Gen 0 GC за интервал обновления | Само по себе большое число не аномалия. Если Gen 2 GC Count случается раз в несколько секунд или чаще — разбирать |
| % Time in GC since last GC | Доля времени, ушедшего в GC с предыдущей сборки | Если постоянно больше 10%, имеет смысл снижать выделения (смотреть через --profile gc-verbose) |
| ThreadPool Queue Length | Число элементов в очереди | В норме почти 0. Растёт и не возвращается = пул исчерпан, подозревайте блокирующие вызовы |
| ThreadPool Thread Count | Число потоков пула | Нагрузка стабильна, а число растёт ступеньками = то же самое |
| Exception Count | Число исключений | Если исключения идут постоянно, ищите места, где ими пользуются как потоком управления |
| Monitor Lock Contention Count | Число конфликтов при захвате блокировки | Заметный рост = конкуренция за блокировку. Дальше — сбор ThreadTime в главе 6 |
Важнее порога — как значение движется со временем. То, что растёт и падает вместе с нагрузкой и затем выходит на плато, обычно здорово. То, что не возвращается после снятия нагрузки, — объект расследования. Как читать тенденции по памяти, подробно разобрано в статье про ожидание GC и утечки.
4. Снимаем трассу через dotnet-trace
dotnet-trace — средство сбора на базе EventPipe.6 Установка и базовый сбор выглядят так.
dotnet tool install --global dotnet-trace
dotnet-trace ps
dotnet-trace collect --process-id <PID> --duration 00:00:00:30
Без параметров используется профиль по умолчанию: основные события runtime и сэмплирование потоков. Профиль с именем cpu-sampling когда-то существовал и с тех пор снят; сейчас по умолчанию сочетаются dotnet-common и dotnet-sampled-thread-time.6 Под задачу можно взять --profile gc-verbose (GC и выборки выделений объектов) или --profile gc-collect (только факты GC, с малой нагрузкой).
Чтобы вместе с остальным снять свой поставщик EventSource из предыдущей статьи, добавьте --providers.
dotnet-trace collect --process-id <PID> --providers KomuraSoft-OrderService
Результат — файл .nettrace. Открыть его можно тремя способами: в Visual Studio, в PerfView или, преобразовав в формат speedscope, в браузере.6
dotnet-trace convert trace.nettrace --format Speedscope
Формат speedscope — лёгкий flame graph на speedscope.app. Им удобно интуитивно увидеть, «под какой функцией ушло время».
Чем открывать, проще решать по вопросу кому показывать результат.
| Ситуация | Что удобнее | Почему |
|---|---|---|
| Самим дойти до функции-причины | PerfView | Есть сводка ByName, сужение через GroupPats/Fold, вырезание интервала (глава 5) |
| Показать команде или заказчику «вот здесь тяжело» | speedscope | PerfView ставить не нужно, открывается в браузере. Flame graph читается и без пояснений |
| Смотреть не из Windows | speedscope | PerfView только под Windows (глава 2). Разработчикам на macOS и Linux отдавайте это |
Итого: PerfView — для расследования, speedscope — для показа. Точечный разбор до имени функции сильнее получается в Stack Viewer PerfView, поэтому дальше — он.
5. ЦП в PerfView — как читать Stack Viewer
PerfView — бесплатное средство расследования производительности от Microsoft. Достаточно скачать один PerfView.exe со страницы релизов на GitHub, установка не нужна.7
5.1 Сбор
Если собирать через GUI, последовательность такая — вплоть до того, куда нажимать.
- Запустите
PerfView.exeот имени администратора (для старта сеанса ETW нужны права администратора3) - В меню выберите Collect > Collect (сочетание Alt+C). Откроется диалог сбора и запросит имя создаваемого файла данных1
- Состав сбора задают флажки в этом диалоге. Если ничего не менять, пишутся выборки ЦП и основные события CLR. Чтобы смотреть ещё и ожидания, включите флажок Thread Time (глава 6)1
- Нажмите Start Collection
- Воспроизведите операцию, которую измеряете (это и есть объект измерения — лишние действия не вставляйте)
- Нажмите Stop Collection. После остановки пойдут слияние данных и разрешение символов, и появится
.etl.zipс именем из шага 2
То же из командной строки выглядит так (её тоже запускают от администратора3).
PerfView collect /nogui /acceptEULA /maxCollectSec:30
Сбор по умолчанию включает выборки ЦП раз в миллисекунду на каждом процессоре (со стеком вызовов) и основные события CLR.1 Накладные расходы в этой конфигурации обычно оценивают в несколько процентов.8
5.2 Как читать CPU Stacks
Откройте результат (.etl.zip) и в «CPU Stacks» выберите целевой процесс — откроется Stack Viewer.
С первого взгляда элементов много, поэтому сначала сопоставьте, что где лежит. Экран делится на «поля фильтров сверху» и «сетку с вкладками снизу».
| Место на экране | Имя | Роль |
|---|---|---|
| Поля сверху | Start / End | Интервал отображения (миллисекунды от начала трассы). Им вырезают один медленный прогон (глава 7) |
| Поля сверху | IncPats / ExcPats | Какие стеки включить / исключить. Ими сужают процесс или модуль |
| Поля сверху | GroupPats | Правила группировки имён. По умолчанию внешние библиотеки сворачиваются, свой код выступает |
| Поля сверху | Fold % / FoldPats | Мелкие узлы ниже заданной доли складываются в родителя, список становится читаемым |
| Вкладки снизу | ByName | Сводка по функциям. С неё и начинают |
| Вкладки снизу | CallTree | Дерево вызовов сверху вниз. Когда нужна общая картина потока |
| Вкладки снизу | Callers / Callees | Только вызывающие / только вызываемые выбранной функции |
Первое, что смотрят, — два столбца на вкладке ByName.
- Exc (exclusive): сколько выборок функция выполнялась сама. Место, которое реально потребляет ЦП.
- Inc (inclusive): сумма выборок функции и всего, что она вызвала. Показывает, что тяжесть сидит где-то ниже по дереву.
Шаблон чтения: идти сверху по Exc и отделять «это мой код или runtime/библиотека». Если высоко в Exc стоит ваш код, цель — алгоритм или цикл этой функции. Если высоко System.String или JSON-сериализатор, через вкладку Callers по Inc дойдите до того, откуда в вашем коде это вызывают так часто.
Второй обязательный шаг — проверить само число выборок. Выборки ЦП — статистика с шагом 1 мс, при малом числе на них влияет случайность. Ориентир: не меньше 1000 в сумме, лучше около 5000. Если не хватает, повторяйте целевую операцию и удлиняйте сбор.1
Если имена функций своих модулей показываются адресами, символы (PDB) не разрешились. Иметь PDB от артефактов сборки под рукой — это и есть возможность расследовать. Подробнее: «Что такое PDB (Program Database)».
6. «Медленно, хотя ЦП свободен» — время блокировки через ThreadTime
Больше половины практических «тормозов» — это не ЦП, а ожидание: захват блокировки, ответ БД или HTTP, файловый I/O, ожидание через Task.Result, близкое к взаимной блокировке. В выборках ЦП это выглядит как время, когда ЦП вообще не работал, поэтому сбор по умолчанию причину не показывает.
В PerfView при сборе включают параметр Thread Time: дополнительно пишутся события переключения контекста, и по каждому потоку можно вместе смотреть «время на ЦП» и «время в блокировке».1
Включить можно в GUI и в командной строке — результат один.
- В GUI: на шаге 2 из раздела 5.1 откройте диалог Collect > Collect (Alt+C), включите флажок
Thread Timeи только потом жмите Start Collection. В официальном руководстве прямо сказано: если исследуете wall-clock time, в диалоге сбора нужно включить флажок Thread Time.1 Первый камень преткновения — собрать с настройками по умолчанию и удивляться, почему времени блокировки нет. - В командной строке: добавьте ключ
/threadTime.
PerfView collect /nogui /acceptEULA /threadTime /maxCollectSec:30
Для разбора откройте представление «Thread Time Stacks». Это тот же Stack Viewer, что у CPU Stacks, но выборки содержат не только время ЦП, но и BLOCKED_TIME (время в блокировке). Сузьте интервал до медленной операции и посмотрите, на каком стеке (каком ожидании) лежит BLOCKED_TIME потока, который вёл работу. Тогда появляется разложение вроде «из 40 секунд 35 ушли на ожидание этого HTTP-вызова».
Если «замирает» интерфейс (после действия несколько секунд нет отклика), почти всегда заблокирован UI-поток. Когда ThreadTime покажет, на чём он стоит, постоянное решение — убрать синхронное ожидание в пользу асинхронного. Как это проектировать, разобрано в «WPF и WinForms: async/await и поток UI».
Осторожно: ThreadTime пишет событие на каждое переключение контекста, объём данных заметно больше, чем при сборе по умолчанию. Держите окно коротким и не снимайте длинные трассы ThreadTime в продакшене.
7. Вместе с EventSource — выделять медленный участок словами бизнеса
И CPU Stacks, и Thread Time — сводки по всему процессу. Если нужно резать по единице бизнес-операции — «где внутри обработки одного заказа ушло время» — работают события Start/Stop EventSource из предыдущей статьи.
Чтобы эту главу можно было пробовать и без предыдущей статьи, ниже — минимальный код своего поставщика. --providers KomuraSoft-OrderService из главы 4 указывает на это Name.
using System.Diagnostics.Tracing;
// [EventSource(Name = ...)] задаёт имя поставщика, которое видят ETW и EventPipe
[EventSource(Name = "KomuraSoft-OrderService")]
public sealed class OrderServiceEventSource : EventSource
{
public static readonly OrderServiceEventSource Log = new OrderServiceEventSource();
[Event(1, Level = EventLevel.Informational)]
public void OrderProcessingStart(string orderId) => WriteEvent(1, orderId);
[Event(2, Level = EventLevel.Informational)]
public void OrderProcessingStop(string orderId) => WriteEvent(2, orderId);
}
На вызывающей стороне достаточно обернуть измеряемый участок.
OrderServiceEventSource.Log.OrderProcessingStart(orderId);
try
{
ProcessOrder(orderId); // бизнес-операция, которую измеряем
}
finally
{
OrderServiceEventSource.Log.OrderProcessingStop(orderId);
}
Имена методов лучше выровнять как …Start / …Stop, а идентификаторы событий держать подряд: тогда в представлении Events в PerfView их проще читать как парный интервал. Stop обязательно из finally, чтобы прогон, который вышел по исключению, не остался «незаконченным интервалом». Как описывать события подробнее (ограничения на типы аргументов, когда какой EventLevel и Keywords) — в предыдущей статье.
При такой инструментировке расследование идёт в таком порядке.
- В приложении заранее выпускают события вроде
OrderProcessingStart/OrderProcessingStop(код выше) - В представлении «Events» PerfView смотрят время этих событий и сужают интервал Stack Viewer фильтрами Start/End до этого окна
- В суженном диапазоне читают разложение ЦП / времени блокировки
Так анализируют именно «тот самый медленный раз», а не тонут в шуме обычной работы. Свои события так же снимает и dotnet-trace, поэтому одну и ту же методику можно применять и на машине разработки, и в продакшене. На практике сложность расследования производительности задаёт не столько владение инструментами, сколько то, есть ли в приложении точки наблюдения.
Итог
- Исходная точка — разделить «тормоза» на CPU-bound и блокировку. Первое видно по сэмплированию ЦП (1 выборка ≈ 1 мс), второе не проявится без сбора ThreadTime.
- Базовое правило: сначала dotnet-trace без прав администратора; PerfView — когда нужны вся машина, нативный код или время блокировки. Снять
.nettraceи читать его в PerfView — тоже обычная связка. - Ядро чтения Stack Viewer — различие exclusive и inclusive; число выборок всегда проверяют.
- Свои события EventSource, которыми режут интервал бизнес-операции, заметно поднимают точность расследования.
Komura Software LLC занимается расследованием проблем производительности Windows-бизнес-приложений — «тормозит», «зависает», «ЦП на максимуме» — и консультациями по инструментированию и проектированию, которые делают приложение проще для измерения. Если есть сценарий воспроизведения и файл трассы, можно заказать и только разбор.
Связанные статьи
- Журнал событий Windows и ETW: как вывести логи бизнес-приложения в стандартные механизмы ОС
- .NET: как отличить ожидание GC от утечки памяти — практические шаги наблюдения, сравнения и доказательства роста памяти
- Как читать аварийные дампы в WinDbg + SOS — практика анализа после сбора
- Сбор дампов сбоев Windows — введение: WER, ProcDump, WinDbg
- Что такое PDB (Program Database) — отладочная информация, символы и Source Link
- Как правильно сравнивать скорость разных версий программы в Windows
- WPF и WinForms: async/await и поток UI
Связанные направления консалтинга
- Расследование сбоев и анализ причин
- Разработка приложений для Windows
- Технические консультации и ревью архитектуры
- Связаться с нами
Источники
-
GitHub, PerfView User’s Guide. Сбор по умолчанию — выборки ЦП раз в миллисекунду на процессор со стеком вызовов; для выводов желательно порядка 1000–5000 выборок; параметр ThreadTime пишет переключения контекста и позволяет разбирать время блокировки (то же есть в Help самого PerfView). ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, EventPipe Overview. EventPipe позволяет трассировать .NET-приложение без компонента с высокими правами вроде прав администратора; область видимости — управляемый код и runtime, события ядра и нативные стеки он не снимает. ↩ ↩2
-
Microsoft Learn, Collect and View EventSource Traces. Для сбора трассы ETW всегда нужны права администратора; PerfView и Visual Studio умеют открывать файлы .nettrace. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, dotnet-counters diagnostic tool. Наблюдение за ЦП, GC, ThreadPool и другими метриками работающего процесса через счётчики System.Runtime. ↩
-
Microsoft Learn, Well-known EventCounters in .NET. Список счётчиков
System.Runtimeи смысл каждого (CPU Usage, GC Heap Size, Gen 0/1/2 GC Count, % Time in GC since last GC, ThreadPool Queue Length, ThreadPool Thread Count, Exception Count, Monitor Lock Contention Count и другие). ↩ -
Microsoft Learn, dotnet-trace diagnostic tool. Команда collect, профили по умолчанию (dotnet-common / dotnet-sampled-thread-time) и снятие профиля cpu-sampling, профили gc-verbose / gc-collect, преобразование в Speedscope / Chromium. ↩ ↩2 ↩3
-
GitHub, microsoft/perfview. PerfView — бесплатное средство анализа производительности для проблем ЦП и памяти; исполняемый файл можно взять прямо со страницы релизов. ↩
-
GitHub, microsoft/perfview Issue #598. Сопровождающий PerfView пишет, что накладные расходы сбора по умолчанию обычно около 3%, а нагрузку можно снизить, изменив интервал выборки через /CpuSampleMSec. ↩
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Что продумать перед заказом разработки Windows-приложения
Перед заказом разработки Windows-приложения разберём, что стоит прояснить: доработка существующего ПО, интеграция с оборудованием, COM/Ac...
Time Travel Debugging — записывать и перематывать ошибки, которые не воспроизводятся в долгоживущих приложениях
Ошибка раз в месяц оставляет в дампе только результат. Записывайте и перематывайте исполнение через WinDbg Time Travel Debugging (TTD): T...
CSV — не «просто текст». Практика CSV в бизнес-приложениях на C# (кодировки, совместимость с Excel, защита от инъекций)
Разбираем типичные сбои ввода-вывода CSV в бизнес-приложениях — самописный разбор через Split(','), искажение текста в Excel из-за UTF-8 ...
Журнал событий Windows и ETW: как вывести логи бизнес-приложения в стандартные механизмы ОС
Журнал событий и ETW — отдельный слой записей, который видят специалисты по эксплуатации и стандартные средства ОС. Разбираем, как раздел...
Как читать аварийные дампы в WinDbg + SOS — практика анализа после сбора
Разбираем, как читать аварийный дамп Windows в WinDbg с расширением SOS: настройка пути к символам, поиск исключений и утечек через !clrs...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Расследование ошибок и причин
Найти причину «тормозов» или «зависаний» — это и есть расследование сбоя, вызванного производительностью.
Разработка приложений для Windows
Спроектировать приложение так, чтобы его было проще измерять (в том числе инструментирование через EventSource), входит в консультации по разработке Windows-приложений.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Что выбрать: PerfView или dotnet-trace?
- Начните с dotnet-trace. Он работает без прав администратора, позволяет целиться в один процесс, а вся операция укладывается в одну команду. Но если нужны стеки нативного кода, картина по всей машине (влияние других процессов и ядра) или время блокировки по отдельным переключениям контекста — без PerfView на базе ETW не обойтись. На практике их часто сочетают: собирают .nettrace через dotnet-trace и открывают файл в PerfView.
- Как это соотносится с профилировщиком Visual Studio?
- Если проблема воспроизводится на машине разработки, инструмент CPU Usage и средства работы с памятью в Visual Studio удобнее, и часто их достаточно. PerfView и dotnet-trace нужны там, где Visual Studio поставить нельзя (проверочная или производственная машина), где сбор и разбор хотят развести по разным машинам, или где в трассу нужно включить события ETW — свои EventSource и события ядра. Visual Studio умеет открывать и файлы .nettrace, которые пишет dotnet-trace.
- Можно ли запускать эти инструменты на производственном сервере?
- Оба рассчитаны на короткий сбор в продакшене, но не безусловно. Ограничьте окно десятками секунд или несколькими минутами, сначала прогоните ту же команду в проверочной среде и посмотрите накладные расходы и размер файла, проверьте свободное место на диске. Сбор ThreadTime (переключения контекста) и трасса выделений дают особенно много событий, файл растёт быстро. В трассе могут оказаться аргументы командной строки и другие сведения — с полученным файлом нужно обращаться осторожно.
- Как разделить роли с WPR/WPA?
- WPR (Windows Performance Recorder) и WPA (Windows Performance Analyzer) — более «системные» средства на той же ETW. Для детального разбора всей ОС — дисковый I/O, питание, время загрузки — сильнее WPR/WPA. Для ЦП, GC и времени блокировки в .NET-приложении удобнее PerfView: отображение заточено под управляемый код. Если цель — расследование бизнес-приложения, в большинстве случаев хватает PerfView и dotnet-trace.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.