Start Debugging
2026-01-21 Обновлено 2026-01-23 dotnetdotnet-10dotnet-9performance Edit on GitHub

Perfetto + dotnet-trace: практический цикл профилирования для .NET 9/.NET 10

Практический цикл профилирования для .NET 9 и .NET 10: захватывайте трассировки с помощью dotnet-trace, визуализируйте их в Perfetto и итеративно разбирайтесь с проблемами CPU, GC и пула потоков.

Самый быстрый способ выйти из тупика “оно тормозит” в .NET - перестать гадать и начать смотреть на временную шкалу. Статья, которая ходит по рукам на этой неделе, показывает чистый рабочий процесс: захват трассировок с помощью dotnet-trace, а затем их анализ в Perfetto (та же экосистема просмотрщика трассировок, которую многие знают по миру Android и Chromium): Using dotnet-trace with Perfetto.

Почему стоит добавить Perfetto в свой инструментарий

Если вы уже используете dotnet-counters или профилировщик, Perfetto его не заменяет. Он его дополняет:

Для приложений .NET 9 и .NET 10 это особенно полезно, когда вы пытаетесь убедиться, что “небольшое” изменение случайно не привнесло лишние аллокации, лишние потоки или новое узкое место синхронизации.

Цикл захвата (сначала воспроизведение, потом трассировка)

Хитрость в том, чтобы относиться к трассировке как к циклу, а не к разовой операции:

Вот минимальная последовательность захвата с использованием глобального инструмента:

dotnet tool install --global dotnet-trace

# Find the PID of the target process (pick one)
dotnet-trace ps

# Capture an EventPipe trace (default providers are usually a good starting point)
dotnet-trace collect --process-id 12345 --duration 00:00:15 --output app.nettrace

В итоге вы получите app.nettrace. Дальше следуйте шагам преобразования/открытия из исходной статьи (точный путь “открыть в Perfetto” зависит от того, какой Perfetto UI вы используете и какой шаг преобразования выберете).

На что смотреть, открыв трассировку

Начните с вопросов, на которые можно ответить за минуты:

Найдя подозрительное окно, вернитесь к коду и внесите точечное изменение (например: уменьшить аллокации, избежать sync-over-async, убрать блокировку с горячего пути запроса или сгруппировать дорогие вызовы).

Один прагматичный шаблон: трассировка в Release без потери символов

Если можете, запускайте медленный путь в Release (ближе к продакшену), но сохраняйте достаточно информации, чтобы рассуждать о фреймах. В SDK-style проектах PDB генерируются по умолчанию; для сеанса профилирования обычно нужны предсказуемые пути вывода:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Configuration>Release</Configuration>
    <DebugType>portable</DebugType>
  </PropertyGroup>
</Project>

Держите всё скучным: стабильный вход, стабильная конфигурация, короткие трассировки, повторение.

Если хотите детальные шаги по Perfetto и скриншоты, исходная статья - лучшая ссылка, которую стоит держать открытой во время прогона цикла: Using dotnet-trace with Perfetto.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад