Udostępnij za pośrednictwem


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

  1. Otwórz zrzut pamięci w programie Visual Studio za pomocą polecenia menu Otwórz > > plik i wybierz zrzut pamięci.

  2. Zwróć uwagę na stronie Podsumowanie zrzutu pamięci nową akcję o nazwie Uruchom analizę diagnosyjną.

    Action - Diagnostics Analysis

  3. 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.

Select diagnostics analyzers

  1. Kliknij przycisk Analizuj, aby rozpocząć proces śledczy

  2. Analizator przedstawi wyniki na podstawie kombinacji informacji o procesie i danych CLR przechwyconych w zrzucie pamięci.

Przeglądanie wyników analizatorów

  1. W tym przypadku analizator znalazł dwa błędy. Wybierz wynik analizatora, aby wyświetlić podsumowanie analizy i sugerowane korygowanie.

    Diagnostics analyzers results

  2. 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".

Moim następnym zadaniem jest znalezienie tego problematycznego kodu.

  1. 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.

  2. W oknie Stos wywołań zostaną wyświetlone metody, które mogą potencjalnie szybko odróżnić kod (SyncOverAsyncExmple.) z kodu platformy (System.).

    Diagnostics analyzers link to call stack

  3. 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.

  4. 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.

    Decompilation

  5. 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.

    Analyze decompiled code