Monitorowanie zasobów domen aplikacji
Monitorowanie zasobów domeny aplikacji (ARM) umożliwia hostom monitorowanie użycia procesora i pamięci przez domenę aplikacji. Jest to przydatne w przypadku hostów, takich jak ASP.NET, które używają wielu domen aplikacji w długotrwałym procesie. Host może zwolnić domenę aplikacji aplikacji, która niekorzystnie wpływa na wydajność całego procesu, ale tylko wtedy, gdy może zidentyfikować problematyczną aplikację. Usługa ARM udostępnia informacje, które mogą służyć do podejmowania takich decyzji.
Na przykład usługa hostingu może mieć wiele aplikacji działających na serwerze ASP.NET. Jeśli jedna aplikacja w procesie zacznie zużywać zbyt dużo pamięci lub zbyt dużo czasu procesora, usługa hostingu może użyć usługi ARM, aby zidentyfikować domenę aplikacji, która powoduje problem.
Usługa ARM jest wystarczająco lekka do użycia w aplikacjach na żywo. Dostęp do informacji można uzyskać za pomocą śledzenia zdarzeń dla systemu Windows (ETW) lub bezpośrednio za pośrednictwem zarządzanych lub natywnych interfejsów API.
Włączanie monitorowania zasobów
Arm można włączyć na cztery sposoby: podając plik konfiguracji, gdy środowisko uruchomieniowe języka wspólnego (CLR) jest uruchamiane, przy użyciu niezarządzanego interfejsu API hostingu, przy użyciu kodu zarządzanego lub przez nasłuchiwanie zdarzeń ETW usługi ARM.
Gdy tylko usługa ARM jest włączona, rozpoczyna zbieranie danych we wszystkich domenach aplikacji w procesie. Jeśli domena aplikacji została utworzona przed włączeniem usługi ARM, zbiorcze dane są uruchamiane po włączeniu usługi ARM, a nie podczas tworzenia domeny aplikacji. Po włączeniu usługi ARM nie można jej wyłączyć.
Możesz włączyć usługę ARM podczas uruchamiania środowiska CLR, dodając element appDomainResourceMonitoring> do pliku konfiguracji i ustawiając atrybut na
true
enabled
.< Wartość (wartośćfalse
domyślna) oznacza tylko, że usługa ARM nie jest włączona podczas uruchamiania. Można ją aktywować później przy użyciu jednego z innych mechanizmów aktywacji.Host może włączyć usługę ARM, żądając interfejsu hostingu ICLRAppDomainResourceMonitor . Po pomyślnym uzyskaniu tego interfejsu usługa ARM jest włączona.
Kod zarządzany może włączyć usługę ARM, ustawiając właściwość statyczną (
Shared
w Visual Basic) AppDomain.MonitoringIsEnabled natrue
. Po ustawieniu właściwości usługa ARM jest włączona.Po uruchomieniu usługi ARM można włączyć, słuchając zdarzeń ETW. Usługa ARM jest włączona i rozpoczyna wywoływanie zdarzeń dla wszystkich domen aplikacji po włączeniu dostawcy
Microsoft-Windows-DotNETRuntime
publicznego przy użyciu słowa kluczowegoAppDomainResourceManagementKeyword
. Aby skorelować dane z domenami aplikacji i wątkami, należy również włączyć dostawcęMicrosoft-Windows-DotNETRuntimeRundown
za pomocą słowa kluczowegoThreadingKeyword
.
Korzystanie z usługi ARM
Usługa ARM zapewnia łączny czas procesora używany przez domenę aplikacji i trzy rodzaje informacji o użyciu pamięci.
Łączny czas procesora dla domeny aplikacji w sekundach: jest obliczany przez dodanie czasów wątków zgłaszanych przez system operacyjny dla wszystkich wątków, które spędziły czas wykonywania w domenie aplikacji w okresie istnienia. Zablokowane lub śpiące wątki nie używają czasu procesora. Gdy wątek wywołuje kod natywny, czas, jaki wątek spędza w kodzie natywnym, jest uwzględniony w liczbie domen aplikacji, w której wykonano wywołanie.
Zarządzany interfejs API: AppDomain.MonitoringTotalProcessorTime właściwość.
Interfejs API hostingu: metoda ICLRAppDomainResourceMonitor::GetCurrentCpuTime .
Zdarzenia ETW:
ThreadCreated
,ThreadAppDomainEnter
iThreadTerminated
zdarzenia. Aby uzyskać informacje o dostawcach i słowach kluczowych, zobacz "AppDomain Resource Monitoring Events" in CLR ETW Events (Zdarzenia monitorowania zasobów AppDomain w zdarzeniach CLR ETW).
Łączna liczba alokacji zarządzanych przez domenę aplikacji w okresie jej istnienia w bajtach: Łączna alokacja nie zawsze odzwierciedla użycie pamięci przez domenę aplikacji, ponieważ przydzielone obiekty mogą być krótkotrwałe. Jeśli jednak aplikacja przydziela i zwalnia ogromną liczbę obiektów, koszt alokacji może być znaczący.
Zarządzany interfejs API: AppDomain.MonitoringTotalAllocatedMemorySize właściwość.
Interfejs API hostingu: ICLRAppDomainResourceMonitor::GetCurrentAllocated , metoda.
Zdarzenia ETW:
AppDomainMemAllocated
zdarzenie,Allocated
pole.
Pamięć zarządzana w bajtach, do których odwołuje się domena aplikacji i która przetrwała najnowszą pełną, blokującą kolekcję: Ta liczba jest dokładna dopiero po pełnym, blokującym kolekcji. (Jest to w przeciwieństwie do kolekcji współbieżnych, które występują w tle i nie blokują aplikacji). Na przykład GC.Collect() przeciążenie metody powoduje pełne blokowanie kolekcji.
Zarządzany interfejs API: AppDomain.MonitoringSurvivedMemorySize właściwość.
Interfejs API hostingu: ICLRAppDomainResourceMonitor::GetCurrentSurvived , metoda,
pAppDomainBytesSurvived
parametr.Zdarzenia ETW:
AppDomainMemSurvived
zdarzenie,Survived
pole.
Łączna ilość pamięci zarządzanej w bajtach, do których odwołuje się proces, i która przetrwała najnowszą pełną, blokującą kolekcję: Pamięć przetrwana dla poszczególnych domen aplikacji może być porównywana z tą liczbą.
Zarządzany interfejs API: AppDomain.MonitoringSurvivedProcessMemorySize właściwość.
Interfejs API hostingu: ICLRAppDomainResourceMonitor::GetCurrentSurvived , metoda,
pTotalBytesSurvived
parametr.Zdarzenia ETW:
AppDomainMemSurvived
zdarzenie,ProcessSurvived
pole.
Określanie, kiedy występuje pełna kolekcja blokująca
Aby określić, kiedy liczba przetrwanych pamięci jest dokładna, musisz wiedzieć, kiedy właśnie wystąpiła pełna, blokująca kolekcja. Metoda wykonywania tej czynności zależy od interfejsu API używanego do badania statystyk usługi ARM.
Zarządzany interfejs API
Jeśli używasz właściwości AppDomain klasy, możesz użyć GC.RegisterForFullGCNotification metody , aby zarejestrować się w celu otrzymywania powiadomień o pełnych kolekcjach. Używany próg nie jest ważny, ponieważ oczekujesz na ukończenie kolekcji, a nie podejście do kolekcji. Następnie można wywołać metodę GC.WaitForFullGCComplete , która blokuje pełną kolekcję do momentu ukończenia pełnej kolekcji. Można utworzyć wątek, który wywołuje metodę w pętli i wykonuje dowolną niezbędną analizę za każdym razem, gdy metoda zwróci.
Alternatywnie można okresowo wywołać metodę GC.CollectionCount , aby sprawdzić, czy liczba kolekcji generacji 2 wzrosła. W zależności od częstotliwości sondowania ta technika może nie zapewniać tak dokładnego wskazania wystąpienia pełnej kolekcji.
Interfejs API hostingu
Jeśli używasz niezarządzanego interfejsu API hostingu, host musi przekazać clR implementację interfejsu IHostGCManager . ClR wywołuje metodę IHostGCManager::SuspensionEnding po wznowieniu wykonywania wątków, które zostały zawieszone podczas wykonywania kolekcji. ClR przekazuje generowanie ukończonej kolekcji jako parametr metody, więc host może określić, czy kolekcja była pełna, czy częściowa. Implementacja metody IHostGCManager::SuspensionEnding może wykonywać zapytania dotyczące pamięci, aby upewnić się, że liczby są pobierane natychmiast po ich zaktualizowaniu.