Изоляция проблемы с производительностью (C#, Visual Basic, F#)

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

Вместо того, чтобы предоставить пошаговые инструкции, здесь вы узнаете, как эффективно использовать средства профилирования и как интерпретировать данные. Как и средство использования ЦП, средство счетчиков .NET также является хорошей отправной точкой для исследования производительности. После выявления интересных данных можно использовать другие средства профилирования для более глубокого изучения. Чтобы сравнить средства, см. раздел "Какой инструмент должен выбрать"?

Сведения о примере приложения

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

Запуск исследования

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

Для сбора данных требуются следующие действия (не показанные в этой статье):

  • Задайте для приложения сборку выпуска.
  • Выберите средство счетчиков .NET в профилировщике производительности (ALT+F2). (Последующие шаги включают инструментирование.)
  • В профилировщике производительности запустите приложение.

Проверка счетчиков производительности

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

  • CPU Usage. Просмотрите этот счетчик, чтобы узнать, возникает ли проблема с производительностью с высоким или низким потреблением ЦП. Это может быть ключом к конкретным типам проблем с производительностью. Например:
    • При высоком использовании ЦП используйте средство использования ЦП для выявления областей, где можно оптимизировать код. Руководство по оптимизации кода см . в руководстве по началу работы с этим руководством.
    • При низком использовании ЦП используйте инструментирование, чтобы определить количество вызовов и среднее время функции на основе времени настенные часы. Это может помочь выявить такие проблемы, как состязание или нехватка пула потоков.
  • Allocation Rate. Для запросов на обслуживание веб-приложений скорость должна быть достаточно стабильной.
  • GC Heap Size. Просмотрите этот счетчик, чтобы узнать, растет ли использование памяти постоянно и потенциально утечки. Если это кажется высоким, вы можете использовать один из средств использования памяти.
  • Threadpool Thread Count. Для запросов на обслуживание веб-приложений просмотрите этот счетчик, чтобы узнать, держится ли число потоков устойчивым или растет на стабильном уровне.

Вот пример, показывающий, как низкий, в то время как CPU UsageThreadPool Thread Count относительно высокий.

Снимок экрана: счетчики, отображаемые в средстве счетчиков .NET.

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

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

Изучение количества вызовов и данных о времени

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

При загрузке диагностических данных сначала проверьте начальную страницу отчета .diagsession , в которую отображаются Top Insights и горячий путь. В трассировке инструментирования горячий путь отображает путь кода с самым длинным временем функции в приложении. Эти разделы могут предоставлять советы по быстрому выявлению проблем с производительностью, которые можно улучшить.

В собранной трассировке используйте ссылку "Открыть сведения " в отчете и выберите "Диаграмма пламени".

Снимок экрана:

Визуализация "Диаграмма пламени" показывает, что QueryCustomerDB функция отвечает за значительную часть времени выполнения приложения.

Щелкните правой кнопкой мыши функцию QueryCustomerDB и выберите "Вид" в дереве вызовов.

Снимок экрана: дерево вызовов в инструментировании.

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

Относительно времени, затраченного на другие функции, значения Self и Avg Self для QueryCustomerDB функции очень высоки. В отличие от Total и Avg Total, самозаверяемые значения исключают время, затраченное на другие функции, поэтому это хорошее место для поиска узких мест производительности.

Совет

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

Дважды щелкните QueryCustomerDB функцию, чтобы отобразить исходный код для функции.

public ActionResult<string> QueryCustomerDB()
{

    Task dbTask = QueryCustomerFromDbAsync("Dana");
    return "success:tasksleepwait";
}

С небольшим исследованием мы обнаружили, что этот код вызывает асинхронный API без использования ожиданий. Это шаблон кода синхронизации над асинхронным кодом, который является распространенной причиной голода threadpool и может блокировать потоки.

Для разрешения используйте await.

public async Task<ActionResult<string>> TaskAsyncWait()
{
    Customer c = await PretendQueryCustomerFromDbAsync("Dana");
    return "success:taskasyncwait";
}

Если возникают проблемы с производительностью, связанные с запросами к базе данных, можно использовать средство базы данных для изучения того, являются ли некоторые вызовы медленнее. Эти данные могут указывать на возможность оптимизации запросов. Руководство по оптимизации кода см. в руководстве по использованию средства базы данных для изучения проблемы с производительностью. Средство базы данных поддерживает .NET Core с ADO.NET или Entity Framework Core.

Чтобы получить визуализации в Visual Studio для отдельного поведения потока, можно использовать окно Parallel Stacks во время отладки. В этом окне показаны отдельные потоки, а также сведения о потоках ожидания, потоках, которые они ожидают, и взаимоблокировках.

Дополнительные сведения о нехватке пула потоков см. в разделе "Обнаружение голода threadpool".

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

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