Отслеживание ресурсов домена приложения

Функция наблюдения за ресурсами доменов приложений (ARM) позволяет узлам отслеживать загрузку ЦП и использование памяти доменом приложения. Это полезно для некоторых узлов, таких как ASP.NET, которые используют несколько доменов приложений в длительных процессах. Узел может выгрузить домен приложения, если его работа понижает производительность процесса в целом. Но для нужно определить проблемное приложение. ARM предоставляет сведения, которые помогут решить эту задачу.

Например, на сервере ASP.NET службы размещения может выполняться несколько приложений. Если одно из приложений процесса потребляет слишком много памяти или процессорного времени, служба размещения с помощью ARM может определить проблемный домен приложения.

Функция ARM достаточно нетребовательна к ресурсам, что позволяет применять ее в работающих приложениях. Нужную информацию можно получить с помощью трассировки событий для Windows (ETW), а также управляемых или собственных интерфейсов API.

Включение наблюдения за ресурсами

ARM можно включить четырьмя способами: в файле конфигурации при запуске общеязыковой среды выполнения (CLR), через неуправляемый интерфейс API размещения, в управляемом коде или ожидая передачи событий трассировки событий Windows ARM.

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

  • Вы можете включить ARM при запуске СРЕДЫ CLR, добавив элемент appDomainResourceMonitoring> в файл конфигурации и задав атрибутtrue.enabled< Значение false (по умолчанию) просто означает, что ARM не включается автоматически при запуске. ARM можно включить позже с помощью любого другого механизма активации.

  • Узел может включить ARM, подав запрос на интерфейс размещения ICLRAppDomainResourceMonitor. ARM включается после успешного получения этого интерфейса.

  • Чтобы включить ARM из управляемого кода, задайте для статического свойства AppDomain.MonitoringIsEnabled (Shared в Visual Basic) значение true. ARM включается сразу после изменения этого свойства.

  • Чтобы включить ARM после запуска, используйте ожидание передачи данных от функции трассировки событий Windows. ARM включается и начинает создавать события для всех доменов приложений при активации общего поставщика Microsoft-Windows-DotNETRuntime с помощью ключевого слова AppDomainResourceManagementKeyword. Чтобы связать данные с потоками и доменами приложений, также нужно включить поставщик Microsoft-Windows-DotNETRuntimeRundown с помощью ключевого слова ThreadingKeyword.

Использование ARM

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

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

  • Общий объем выделенной управляемой памяти для домена приложения за все время его существования (в байтах). Общий объем выделенной памяти не всегда правильно отражает использование памяти доменом приложения, так как объекты могут выделяться на короткий промежуток времени. Но накладные расходы могут оказаться существенными, если приложение часто выделяет и освобождает большое количество объектов.

  • Управляемая память (в байтах), которая используется доменом приложения и осталась выделенной после последней полной блокирующей сборки мусора. Этот параметр имеет смысл, только если выполнялась полная блокирующая сборка (Это отличается от параллельных коллекций, которые происходят в фоновом режиме и не блокируют приложение.) Например, перегрузка GC.Collect() метода вызывает полную блокировку коллекции.

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

Как определить время полной блокирующей сборки мусора

Чтобы определить точность сведений об оставшемся объеме памяти, нужно узнать время последней полной блокирующей сборки. Метод определения времени зависит от того, какой API-интерфейс вы используете для изучения статистики ARM.

Управляемый интерфейс API

Если вы используете свойства класса AppDomain, метод GC.RegisterForFullGCNotification позволяет зарегистрироваться для получения уведомлений о полных сборках. Указываемое здесь пороговое значение не играет роли, так как вас интересует только завершение сборки, а не ее приближение. После этого вызовите метод GC.WaitForFullGCComplete, который блокируется до завершения полной сборки. Вы можете создать отдельный поток, который вызывает этот метод в цикле и проводит анализ данных при каждом завершении метода.

Кроме того, вы можете периодически вызвать метод GC.CollectionCount, чтобы отслеживать увеличение количества сборок для поколения 2. В зависимости от частоты опроса такой подход не всегда будет давать точные сведения о времени выполнения полной сборки мусора.

Интерфейс API размещения

Если вы используете API размещения, а не управляемый API, узел должен передать в среду CLR реализацию интерфейса IHostGCManager. Среда CLR вызывает метод IHostGCManager::SuspensionEnding из этого интерфейса, когда возобновляет выполнение потоков, приостановленных на время сбора мусора. Среда CLR передает в параметре этого метода номер поколения выполненной сборки. Это позволяет узлу определить тип сборки (полная или частичная). Вы можете поместить запросы данных оставшейся памяти в реализацию метода IHostGCManager::SuspensionEnding, чтобы получать их сразу же по мере обновления.

См. также