Udostępnij za pośrednictwem


Mierzenie użycia pamięci w Visual Studio (C#, Visual Basic, C++, F#)

Znajdowanie przecieków pamięci i nieefektywnej pamięci podczas debugowania za pomocą narzędzia diagnostycznego zintegrowanego z debugerem użycie pamięci. Narzędzie Użycie pamięci umożliwia wykonanie jednej lub więcej migawek sterty zarządzanej i natywnej pamięci, aby ułatwić zrozumienie wpływu użycia pamięci przez typy obiektów. Możesz również analizować użycie pamięci bez dołączonego debugera lub celowania w działającą aplikację. Aby uzyskać więcej informacji, zobacz Uruchamianie narzędzi profilowania w kompilacjach wydania lub debugowania. Aby uzyskać informacje na temat wybierania najlepszego narzędzia do analizy pamięci dla Twoich potrzeb, zobacz Wybierz narzędzie do analizy pamięci.

Mimo że migawki pamięci można zbierać w dowolnym momencie w narzędziu Memory Usage, możesz użyć debugera Visual Studio do kontrolowania sposobu wykonywania aplikacji podczas badania problemów z wydajnością. Ustawianie punktów przerwania, kroków, przerwania wszystkich i innych akcji debugera może pomóc w skoncentrowaniu badań wydajności na ścieżkach kodu, które są najbardziej istotne. Wykonanie tych akcji podczas działania aplikacji może wyeliminować szum z kodu, który cię nie interesuje i może znacznie skrócić czas potrzebny do zdiagnozowania problemu.

Napiwek

Możesz również użyć agenta GitHub Copilot Profiler aby uzyskać wskazówki oparte na sztucznej inteligencji na potrzeby zbierania i analizowania śladów pamięci.

Ważny

Zintegrowane z debugerem narzędzia diagnostyczne są obsługiwane w przypadku programowania .NET w Visual Studio, w tym asp.NET, ASP.NET Core, programowania natywnego/C++ oraz aplikacji mieszanych (.NET i natywnych).

Nauczysz się:

  • Zrób migawki pamięci
  • Analizowanie danych użycia pamięci

Jeśli Memory Usage nie udostępnia potrzebnych danych, inne narzędzia profilujące w Performance Profiler dostarczają różnych rodzajów informacji, które mogą być dla Ciebie pomocne. W wielu przypadkach wąskie gardło wydajności aplikacji może być spowodowane przez coś innego niż pamięć, takie jak procesor CPU, renderowanie interfejsu użytkownika lub czas żądania sieciowego.

Notatka

Obsługa niestandardowego alokatora Profiler pamięci natywnej działa, zbierając dane alokacji zdarzeń ETW emitowane podczas działania. Alokatory w zestawach CRT i Windows SDK zostały opatrzone adnotacjami na poziomie kodu źródłowego, co umożliwia przechwycenie danych dotyczących alokacji. Jeśli piszesz własne alokatory, każda funkcja, która zwraca wskaźnik do nowo przydzielonej pamięci na stercie, może być oznaczona przy użyciu __declspec(alokator), jak pokazano w tym przykładzie dla myMalloc:

__declspec(allocator) void* myMalloc(size_t size)

Zbieranie danych użycia pamięci

  1. Otwórz project, które chcesz debugować w Visual Studio i ustaw punkt przerwania w aplikacji w miejscu, w którym chcesz rozpocząć badanie użycia pamięci.

    Jeśli masz obszar, w którym podejrzewasz problem z pamięcią, ustaw pierwszy punkt przerwania przed wystąpieniem problemu z pamięcią.

    Napiwek

    Ponieważ może to być trudne do przechwycenie profilu pamięci interesującej Cię operacji, gdy aplikacja często przydziela i zwalnia pamięć, ustaw punkty przerwania na początku i na końcu operacji (lub przeprowadzaj krokowo przez operację), aby znaleźć dokładny punkt, w którym zmieniła się pamięć.

  2. Ustaw drugi punkt przerwania na końcu funkcji lub regionu kodu, który chcesz przeanalizować (lub po wystąpieniu podejrzanego problemu z pamięcią).

  3. Okno narzędzi diagnostycznych pojawi się automatycznie, chyba że zostało wyłączone. Aby ponownie wyświetlić okno, kliknij pozycję DebugujWindowsPokaż narzędzia diagnostyczne.

  4. Wybierz użycie pamięci, korzystając z ustawienia Wybierz narzędzia na pasku narzędzi.

    Zrzut ekranu przedstawiający okno Narzędzia diagnostyczne z narzędziem Użycie pamięci wybranym na liście rozwijanej Wybierz narzędzia.

    Zrzut ekranu przedstawiający okno Narzędzia diagnostyczne z narzędziem Użycie pamięci wybranym na liście rozwijanej Wybierz narzędzia.

  5. Kliknij pozycję Debugowanie/Rozpocznij debugowanie (lub Uruchom na pasku narzędzi lub F5).

    Po zakończeniu ładowania aplikacji zostanie wyświetlony widok Podsumowanie narzędzi diagnostycznych.

    Zrzut ekranu przedstawiający kartę Podsumowanie narzędzi diagnostycznych z wykresem osi czasu użycia pamięci i wykresem pamięci procesu.

    Notatka

    Ponieważ zbieranie danych pamięci może mieć wpływ na wydajność debugowania aplikacji natywnych lub mieszanych, migawki pamięci są domyślnie wyłączone. Aby włączyć migawki w aplikacjach w trybie natywnym lub mieszanym, uruchom sesję debugowania (skrót klawiszowy: F5). Po wyświetleniu okna Narzędzia diagnostyczne wybierz kartę Użycie pamięci, a następnie wybierz Profilowanie sterty.

    Zrzut ekranu przedstawiający pasek narzędzi Użycie pamięci z wyróżnionym przyciskiem Profilowanie sterty w celu włączenia migawek dla aplikacji w trybie natywnym lub mieszanym.

    Zatrzymaj (Klawisz skrótu: ShiftF5) i uruchom ponownie debugowanie.

    Zrzut ekranu przedstawiający kartę Podsumowanie narzędzi diagnostycznych z wykresem osi czasu użycia pamięci i wykresem pamięci procesu.

    Notatka

    Ponieważ zbieranie danych pamięci może mieć wpływ na wydajność debugowania aplikacji natywnych lub mieszanych, migawki pamięci są domyślnie wyłączone. Aby włączyć migawki w aplikacjach w trybie natywnym lub mieszanym, uruchom sesję debugowania (skrót klawiszowy: F5). Po wyświetleniu okna Narzędzia diagnostyczne wybierz kartę Użycie pamięci, a następnie wybierz Profilowanie sterty.

    Zrzut ekranu przedstawiający pasek narzędzi Użycie pamięci z wyróżnionym przyciskiem Profilowanie sterty w celu włączenia migawek dla aplikacji w trybie natywnym lub mieszanym.

    Zatrzymaj (Klawisz skrótu: ShiftF5) i uruchom ponownie debugowanie.

  6. Aby utworzyć migawkę na początku sesji debugowania, wybierz pozycję Utwórz migawkę na pasku narzędzi podsumowania użycia pamięci . (Może to również pomóc w ustawieniu punktu przerwania).

    Zrzut ekranu przedstawiający pasek narzędzi podsumowania 'Użycie pamięci' z przyciskiem 'Wykonaj migawkę'.

    Napiwek

    Aby utworzyć punkt odniesienia dla porównań pamięci, rozważ utworzenie migawki na początku sesji debugowania.

  7. Uruchom scenariusz, który spowoduje uderzenie w pierwszy punkt przerwania.

  8. Podczas gdy debuger jest wstrzymany w pierwszym punkcie przerwania, wybierz pozycję Wykonaj migawkę na pasku narzędzi podsumowania Użycie pamięci.

  9. Naciśnij F5, aby uruchomić aplikację do momentu osiągnięcia drugiego punktu przerwania.

  10. Teraz wykonaj kolejną migawkę.

W tym momencie możesz rozpocząć analizowanie danych.

Jeśli masz problemy ze zbieraniem lub wyświetlaniem danych, zobacz Rozwiązywanie błędów profilowania i naprawianie problemów.

Analizowanie danych użycia pamięci

Wiersze tabeli podsumowania Użycia pamięci zawierają listę migawek wykonanych podczas sesji debugowania oraz udostępniają linki do bardziej szczegółowych widoków.

Zrzut ekranu przedstawiający tabelę podsumowania użycia pamięci z dwiema migawkami, zawierającą kolumny dla obiektów, rozmiaru sterty oraz ich różnic.

Nazwa kolumny zależy od trybu debugowania wybranego we właściwościach projektu: .NET, natywny lub mieszany (zarówno .NET, jak i natywny).

  • Kolumna Objects (Diff) (.NET) lub Allocations (Diff) (C++) wyświetla liczbę obiektów w .NET lub pamięci natywnej podczas wykonywania migawki.

  • W kolumnie Heap Size (Diff) wyświetlana jest liczba bajtów zarówno w stertach .NET, jak i natywnych.

Po utworzeniu wielu migawek komórki tabeli podsumowania zawierają zmianę wartości między migawką wiersza a poprzednią migawką.

Aby przeanalizować użycie pamięci, kliknij jeden z linków, który otwiera szczegółowy raport użycia pamięci:

  • Aby wyświetlić szczegóły różnicy między bieżącą migawką a poprzednią migawką, wybierz link zmiany z lewej strony strzałki (Zwiększenie użycia pamięcizwiększenie użycia pamięci). Czerwona strzałka wskazuje wzrost użycia pamięci, a zielona strzałka wskazuje spadek.

Napiwek

Aby szybciej identyfikować problemy z pamięcią, raporty różnic są sortowane według typów obiektów, które najbardziej zwiększyły swoją liczbę (kliknij link zmiany w kolumnie Objects (Różnice)) lub które najbardziej zwiększyły rozmiar sterty (kliknij link zmiany w kolumnie Rozmiar sterty (Różnice)).

  • Aby wyświetlić szczegóły tylko wybranej migawki, kliknij link bez zmian.

    Raport zostanie wyświetlony w osobnym oknie.

Raporty dotyczące typów zarządzanych

W tabeli podsumowania Użycie pamięci wybierz bieżący link komórki Objects (Diff).

Zrzut ekranu przedstawiający raport typu zarządzanego. raport typu zarządzanego

Notatka

W przypadku kodu .NET, ikona View Details (Ikona wystąpienia w kolumnie Typ obiektu) jest dostępna tylko podczas korzystania z narzędzia do analizy użycia pamięci zintegrowanego z debugerem lub gdy otwierasz migawkę sterty i wybierasz opcję Debugowanie pamięci zarządzanej.

Górne okienko pokazuje liczbę i rozmiar typów w migawce, w tym rozmiar wszystkich obiektów, do których odwołuje się typ (rozmiar łączny).

Drzewo Ścieżki do korzenia w dolnym okienku wyświetla obiekty odwołujące się do typu wybranego w górnym okienku. Moduł odśmieceń pamięci .NET czyści pamięć dla obiektu tylko wtedy, gdy ostatni typ odwołujący się do niego został zwolniony. Aby uzyskać więcej informacji na temat używania drzewa ścieżek do katalogu głównego, zobacz Analizowanie ścieżki gorącej do katalogu głównego.

Zrzut ekranu przedstawiający raport typu zarządzanego. raport typu zarządzanego

Notatka

W przypadku kodu .NET, ikona View Instances (Ikona wystąpienia w kolumnie Typ obiektuDBG_MMA_InstancesIcon) jest dostępna tylko podczas korzystania z zintegrowanego z debugerem narzędzia użycia pamięci lub podczas otwierania migawki sterty i wybranie Debugowanie pamięci zarządzanej.

Górne okienko pokazuje liczbę i rozmiar typów w migawce, w tym rozmiar wszystkich obiektów, do których odwołuje się typ (rozmiar łączny).

Drzewo Ścieżki do korzenia w dolnym okienku wyświetla obiekty odwołujące się do typu wybranego w górnym okienku. Moduł odśmieceń pamięci .NET czyści pamięć dla obiektu tylko wtedy, gdy ostatni typ odwołujący się do niego został zwolniony. Aby uzyskać więcej informacji na temat używania drzewa ścieżek do katalogu głównego, zobacz Analizowanie ścieżki gorącej do katalogu głównego.

Drzewo typów referencyjnych pokazuje odwołania, które są przechowywane przez typ wybrany w górnym panelu.

Zrzut ekranu przedstawiający raport o obiektach referencyjnych.

Drzewo typów referencyjnych pokazuje odwołania, które są przechowywane przez typ wybrany w górnym panelu.

Zrzut ekranu przedstawiający raport o obiektach referencyjnych.

Aby wyświetlić wystąpienia wybranego typu w górnym okienku, kliknij ikonę Wyświetl szczegóły obok typu obiektu.

Zrzut ekranu przedstawiający widok Wystąpienia w narzędziu Użycie pamięci.Wystąpienia w narzędziu Użycie pamięci

Widok Instances wyświetla wystąpienia wybranego obiektu w migawki w górnym okienku. W okienku Ścieżki do root i Obiekty, do których odwołuje się, są wyświetlane obiekty odwołujące się do wybranego wystąpienia oraz typy, do których odwołuje się wybrane wystąpienie. Po zatrzymaniu debugera w punkcie, w którym migawka została wykonana, możesz umieścić kursor na komórce Value, aby wyświetlić wartości obiektu w poradzie narzędzia.

Aby wyświetlić wystąpienia wybranego typu w górnym okienku, kliknij ikonę Wyświetl wystąpienia obok typu obiektu.

Zrzut ekranu przedstawiający widok Wystąpienia w narzędziu Użycie pamięci.Wystąpienia w narzędziu Użycie pamięci

Widok Instances wyświetla wystąpienia wybranego obiektu w migawki w górnym okienku. W okienku Ścieżki do root i Obiekty, do których odwołuje się, są wyświetlane obiekty odwołujące się do wybranego wystąpienia oraz typy, do których odwołuje się wybrane wystąpienie. Po zatrzymaniu debugera w punkcie, w którym migawka została wykonana, możesz umieścić kursor na komórce Value, aby wyświetlić wartości obiektu w poradzie narzędzia.

Raporty typów natywnych

Wybierz bieżący link komórki Alokacje (Różnica) lub Rozmiar sterty (Różnica) w tabeli podsumowania użycia pamięci w oknie Narzędzia diagnostyczne .

zrzut ekranu przedstawiający widok typu natywnego.

zrzut ekranu przedstawiający widok typu natywnego.

Widok typów wyświetla liczbę i rozmiar typów w migawce.

  • Wybierz ikonę Szczegóły obok wybranego typu, aby wyświetlić informacje o obiektach tego typu w migawce.

    Widok Instances wyświetla każde wystąpienie wybranego typu. Wybranie wystąpienia powoduje wyświetlenie stosu wywołań, który spowodował utworzenie wystąpienia w okienku stosu wywołań alokacji . (Te informacje są dostępne tylko podczas debugowania).

    Zrzut ekranu widoku instancji i panelu stosu wywołań alokacji.

  • Wybierz ikonę Wyświetl wystąpienia obok wybranego typu, aby wyświetlić informacje o obiektach wybranego typu w migawce.

    Widok Instances wyświetla każde wystąpienie wybranego typu. Wybranie wystąpienia powoduje wyświetlenie stosu wywołań, który spowodował utworzenie wystąpienia w okienku stosu wywołań alokacji . (Te informacje są dostępne tylko podczas debugowania).

    Zrzut ekranu widoku instancji i panelu stosu wywołań alokacji.

  • Wybierz Stacks, aby wyświetlić stos alokacji dla wybranego typu.

    zrzut ekranu widoku Stacks.

  • Wybierz Stacks, aby wyświetlić stos alokacji dla wybranego typu.

    zrzut ekranu widoku Stacks.

Szczegółowe informacje o użyciu pamięci

W przypadku pamięci zarządzanej narzędzie Analizy pamięci zapewnia również wiele zaawansowanych wbudowanych funkcji automatycznego wglądu w szczegółowe informacje. Wybierz kartę Insights w raportach Typy Zarządzane, a wyświetli odpowiednie automatyczne analizy, takie jak zduplikowane ciągi, rzadkie tablicei problemy z zarządzaniem zdarzeniami.

Zrzut ekranu przedstawiający widok szczegółowych informacji w narzędziu Użycie pamięci. szczegółowe informacje o użyciu pamięci

Zrzut ekranu przedstawiający widok szczegółowych informacji w narzędziu Użycie pamięci. szczegółowe informacje o użyciu pamięci

W sekcji zduplikowane ciągi przedstawiono listę ciągów, które są przydzielane wiele razy na stercie. Ponadto ta sekcja pokazuje łączną ilość zmarnowanej pamięci, czyli (liczba wystąpień - 1) razy rozmiar ciągu.

W sekcji Tablice rozrzedzone przedstawiono tablice, które są w większości wypełnione elementami zerowymi, co może być nieefektywne pod względem wydajności i użycia pamięci. Narzędzie do analizy pamięci automatycznie wykryje te tablice i pokaże, ile pamięci jest marnowane z powodu tych wartości zerowych.

Sekcja Event Handler Leaks dostępna w Visual Studio 2022 w wersji 17.9 (wersja zapoznawcza 1) pokazuje potencjalne przecieki pamięci, które mogą wystąpić, gdy jeden obiekt subskrybuje zdarzenie innego obiektu. Jeśli wydawca zdarzenia przeżyje subskrybenta, subskrybent pozostaje aktywny, nawet jeśli nie ma do niego żadnych innych referencji. Może to prowadzić do przecieków pamięci, w których nieużywane pamięci nie są prawidłowo zwalniane, co powoduje, że aplikacja będzie używać coraz większej ilości pamięci w czasie.

Niektóre typy są znane z tego, że mają pola, które można odczytać, aby określić rozmiar pamięci natywnej, którą zajmują. Karta Insights przedstawia fałszywe natywne węzły pamięci na wykresie obiektów, które są przechowywane przez obiekty nadrzędne, tak aby interfejs użytkownika rozpoznał je i wyświetlił ich rozmiar i graf referencyjny.

Zrzut ekranu przedstawiający natywny widok informacji w narzędziu Użycie pamięci.natywny widok informacji w narzędziu Użycie pamięci

Raporty zmian (różnic)

  • Wybierz link do zmiany w komórce tabeli podsumowania zakładki Użycie pamięci w oknie Narzędzia diagnostyczne .

    Zrzut ekranu przedstawiający tabelę podsumowania użycia pamięci z linkiem zmiany danych wyróżnionym w komórce migawki.

  • Wybierz migawkę z listy w Porównaj z raportu zarządzanego lub natywnego.

    Zrzut ekranu listy rozwijanej Porównaj do w raporcie Użycie pamięci, pokazujący dostępne migawki do porównania.

    Zrzut ekranu listy rozwijanej Porównaj do w raporcie Użycie pamięci, pokazujący dostępne migawki do porównania.

Raport zmiany dodaje kolumny (oznaczone (Różnice)) do raportu podstawowego, które pokazują różnicę między wartościami migawki podstawowej a migawką porównawczą. Oto jak może wyglądać raport różnic widoku typu natywnego:

Zrzut ekranu widoku różnic typów natywnych.Widok różnic typów natywnych

Zrzut ekranu widoku różnic typów natywnych.Widok różnic typów natywnych

Górne okienko pokazuje liczbę i rozmiar typów w migawce, w tym rozmiar wszystkich obiektów, do których odwołuje się typ (rozmiar łączny).

Blogi i filmy wideo

analizowanie CPU i pamięci podczas debugowania

blog Visual C++: profilowanie pamięci w programie Visual C++ 2015

Następne kroki

W tym samouczku nauczyłeś się, jak zbierać i analizować dane dotyczące użycia pamięci podczas debugowania. Poniżej przedstawiono kilka sugerowanych następnych kroków:

  • Aby przeanalizować użycie pamięci w kompilacjach wydania, zobacz Analizowanie użycia pamięci w profilerze wydajności.
  • Aby poznać ogólne podejście do optymalizowania kodu przy użyciu narzędzi profilowania, zobacz Analiza przypadku: Przewodnik dla początkujących dotyczący optymalizowania kodu.
  • Aby uzyskać wskazówki dotyczące profilowania opartego na sztucznej inteligencji, zobacz Profile aplikacji za pomocą agenta GitHub Copilot Profiler.
  • Aby zapoznać się z omówieniem wszystkich narzędzi profilowania, zobacz Pierwsze spojrzenie na narzędzia profilowania.