Debugowanie zrzutu pamięci zarządzanej za pomocą analizatorów diagnostycznych platformy .NET
Ten samouczek obejmuje następujące kroki:
- Otwieranie zrzutu pamięci
- Wybieranie i wykonywanie analizatorów względem zrzutu
- Przeglądanie wyników analizatorów
- Przechodzenie do problematycznego kodu
W przykładzie opisanym w tym artykule problemem jest to, że aplikacja nie odpowiada na żądania w odpowiednim czasie.
Otwieranie zrzutu pamięci w programie Visual Studio
Otwórz zrzut pamięci w programie Visual Studio za pomocą polecenia menu Otwórz > > plik i wybierz zrzut pamięci.
Zwróć uwagę na stronie Podsumowanie zrzutu pamięci nową akcję o nazwie Uruchom analizę diagnosyjną.
Wybierz tę akcję, aby uruchomić debuger i otworzyć nową stronę Analiza diagnostyczna z listą dostępnych opcji analizatora uporządkowaną według podstawowego objawu.
Wybieranie i wykonywanie analizatorów względem zrzutu
Aby zbadać te objawy, najlepsze opcje są dostępne w obszarze Czas odpowiedzi procesu, ponieważ najlepiej pasuje do problemu w tym przykładzie.
Kliknij przycisk Analizuj, aby rozpocząć proces śledczy
Analizator przedstawi wyniki na podstawie kombinacji informacji o procesie i danych CLR przechwyconych w zrzucie pamięci.
Przeglądanie wyników analizatorów
W tym przypadku analizator znalazł dwa błędy. Wybierz wynik analizatora, aby wyświetlić podsumowanie analizy i sugerowane korygowanie.
Podsumowanie analizy stwierdziło, że "pula wątków CLR doświadcza głodu". Te informacje sugerują, że clR aktualnie używa wszystkich dostępnych wątków puli wątków, co oznacza, że usługa nie może odpowiadać na żadne nowe żądania do momentu wydania wątku.
Uwaga
Korygowanie w tym przypadku to "Nie czekaj synchronicznie na monitorach, zdarzeniach, zadaniu lub innych obiektach, które mogą blokować wątek. Sprawdź, czy możesz zaktualizować metodę tak, aby mogła być asynchroniczna".
Przechodzenie do problematycznego kodu
Moim następnym zadaniem jest znalezienie tego problematycznego kodu.
Kliknięcie linku Pokaż stos wywołań w programie Visual Studio spowoduje natychmiastowe przełączenie się do wątków, które wykazują to zachowanie.
W oknie Stos wywołań zostaną wyświetlone metody, które mogą potencjalnie szybko odróżnić kod (SyncOverAsyncExmple.) z kodu platformy (System.).
Każda ramka stosu wywołań odpowiada metodzie, a kliknięcie dwukrotnie ramek stosu w programie Visual Studio spowoduje przejście do kodu prowadzącego bezpośrednio do tego scenariusza w tym wątku.
W tym przykładzie nie ma symboli ani kodu, jednak na stronie Symbole nie załadowane można wybrać opcję Dekompiluj kod źródłowy.
Poniżej dekompilowanego źródła widać, że asynchroniczne zadanie (ConsumeThreadPoolThread) wywołuje funkcję blokującą synchroniczną.
Uwaga
Metoda "DoSomething()", która zawiera metodę WaitHandle.WaitOne, która blokuje bieżący wątek puli wątków, dopóki nie otrzyma sygnału.
Aby poprawić czas odpowiedzi aplikacji, ważne jest, aby usunąć blokowanie synchronicznego kodu ze wszystkich kontekstów asynchronicznych.