Zrób zrzut stosu

Zrób zrzut stosu, aby sprawdzić, które obiekty w aplikacji wykorzystują pamięć czas przechwytywania i identyfikowanie wycieków pamięci lub zachowania alokacji pamięci który się zacina, zawiesza, a nawet ulega awarii. Szczególnie przydatne jest robi zrzuty stosu po dłuższej sesji użytkownika, kiedy obiekty mogą być nieruchome w pamięci, których już nie powinno być.

Na tej stronie opisujemy narzędzia udostępniane w Android Studio do zbierania analizować zrzuty stosu. Możesz też sprawdzić pamięć aplikacji z poziomu wiersza poleceń za pomocą dumpsys oraz zobaczyć zdarzenia związane z zbieraniem pamięci (GC) w Logcat.

Dlaczego warto przeprowadzić profilowanie pamięci aplikacji

Android zapewnia sterowane środowisko pamięci – gdy system stwierdzi, że aplikacja nie używa już niektórych obiektów, zbieracz śmieci zwalnia nieużywaną pamięć z powrotem do stosu. Sposób, w jaki Android wyszukuje niewykorzystaną pamięć, jest stale ulepszany, ale w pewnym momencie w każdej wersji Androida system musi na krótko wstrzymać działanie kodu. W większości przypadków przerwy są niezauważalne. Jeśli jednak Twoja aplikacja przydziela pamięć szybciej niż system może ją zebrać, może się opóźnić, dopóki zbieracz nie zwolni wystarczającej ilości pamięci, aby zaspokoić Twoje potrzeby. Opóźnienie może spowodować pomijanie klatek przez aplikację i widoczne spowolnienie jej działania.

Nawet jeśli aplikacja nie działa wolniej, w przypadku wycieku pamięci, może zachować nawet jeśli działa w tle. To zachowanie może spowolnić resztę wydajności pamięci systemu przez wymuszanie niepotrzebnego czyszczenia pamięci, zdarzeń. W końcu system będzie musiał zakończyć proces aplikacji, aby odzyskać pamięci. Gdy użytkownik wróci do aplikacji, proces aplikacji musi zostać uruchomiony ponownie całkowicie.

Informacje o praktykach programowania, które mogą zmniejszyć użycie pamięci przez aplikację, znajdziesz w artykule Zarządzanie pamięcią aplikacji.

Omówienie zrzutu stosu

Aby uzyskać zrzut stosu, wybierz zadanie Analiza wykorzystania pamięci (zrzut stosu) (użyj opcji Profilowanie: uruchom aplikację jako debugowaną (pełne dane)), aby uzyskać zrzut stosu. Podczas zrzutu pamięci sterty może tymczasowo wzrosnąć ilość pamięci Java. To normalne, ponieważ zrzut stosu występuje w tym samym procesie co aplikacji i wymaga trochę pamięci, by je zebrać. Po utworzeniu kopii pamięci podręcznej zobaczysz:

Lista zajęć zawiera te informacje:

  • Wydzielenia: liczba wydzielenia w pniu.
  • Rozmiar natywny: łączna ilość pamięci natywnej używanej przez ten typ obiektu (w bajtach). Zobaczysz tutaj pamięć dla niektórych obiektów przydzielonych w Javie, Android używa natywnej pamięci na potrzeby niektórych klas platformy, takich jak Bitmap

  • Shallow Size (Płytka wielkość): łączna ilość pamięci Java używanej przez ten typ obiektu (w bajtach).

  • Przechowywany rozmiar: łączny rozmiar pamięci przechowywanej ze względu na wszystkie instancje tej klasy (w bajtach).

W menu stosu możesz filtrować według określonych stosów:

  • Stos aplikacji (domyślny): główny stos, na którym aplikacja przydziela pamięć.
  • Stos obrazów: obraz rozruchowy systemu zawierający wstępnie wczytywane klasy podczas uruchamiania. Przydziały nigdy się nie zmieniają ani nie znikają.
  • Pamięć alokowana przez Zygote: pamięć alokowana na zapis, z której w systemie Androida wyodrębniany jest proces aplikacji.

Z menu aranżacji wybierz sposób rozmieszczenia przydziałów:

  • Uporządkuj według zajęć (domyślnie): wszystkie alokacje są grupowane według nazwy zajęć.
  • Uporządkuj według pakietu: wszystkie alokacje są grupowane według nazwy pakietu.

Użyj menu zajęć, aby filtrować grupy zajęć:

  • Wszystkie klasy (domyślnie): wyświetla wszystkie klasy, w tym te z bibliotek i zależności.
  • Pokaż wycieki aktywności/fragmentów: pokazuje klasy, które powodują wycieki pamięci.
  • Pokaż zajęcia projektu: wyświetla tylko zajęcia zdefiniowane przez Twój projekt.

Kliknij nazwę zajęć, aby otworzyć panel Instancja. Każda wymieniona instancja zawiera:

  • Głębokość: najmniejsza liczba przeskoków od dowolnego korzenia GC do wybranej instancji.
  • Rozmiar natywny: rozmiar tej instancji w pamięci natywnej. Ta kolumna jest widoczna tylko w Androidzie 7.0 lub nowszym.
  • Płytki rozmiar: rozmiar tej instancji w pamięci Java.
  • Zachowywany rozmiar: rozmiar pamięci, którą dominuje ta instancja (na podstawie drzewo dominacji).

Kliknij instancję, aby wyświetlić szczegóły instancji, w tym pola i odwołania. Typy pól i odwołań to w języku Java typy uporządkowane, tablice oraz proste typy danych. Kliknij prawym przyciskiem myszy pole lub odwołanie, aby przejść do powiązanego wystąpienia lub wiersza w kodzie źródłowym.

  • Pola: zawiera wszystkie pola w tej instancji.
  • Pliki referencyjne: pokazuje wszystkie odwołania do obiektu zaznaczonego w Instancja.

znajdować wycieki pamięci,

Aby szybko odfiltrować zajęcia, które mogą być powiązane z wyciekami pamięci, otwórz menu zajęć i wybierz Pokaż wycieki aktywności/fragmentów. Android Studio wyświetla klasy, które według niego wskazują na wycieki pamięci w przypadku instancji ActivityFragment w aplikacji. Filtr wyświetla takie typy danych:

  • instancji Activity, które zostały zniszczone, ale nadal są używane;
  • Fragment wystąpienia, które nie mają prawidłowego FragmentManager, ale są nadal używane.

Pamiętaj, że filtr może dać fałszywy alarm w tych sytuacjach:

  • Fragment został utworzony, ale nie został jeszcze użyty.
  • Fragment jest przechowywane w pamięci podręcznej, ale nie w ramach FragmentTransaction.

Aby ręcznie szukać wycieków pamięci, przejrzyj listy klas i wystąpieni, aby znaleźć obiekty o dużej wartości Zatrzymany rozmiar. Sprawdź, czy nie występują wycieki pamięci spowodowane przez:

  • długotrwałe odniesienia do Activity, Context, View, Drawable i inne obiekty który może zawierać odwołanie do kontenera Activity lub Context.
  • Niestatyczne klasy wewnętrzne, takie jak Runnable, które mogą zawierać instancję Activity.
  • Pamięci podręczne, w których obiekty są przechowywane dłużej niż jest to konieczne.

Gdy znajdziesz potencjalne wycieki pamięci, użyj kart Wielości i Odwołania na stronie Szczegóły instancji, aby przejść do interesującej Cię instancji lub linii kodu źródłowego.

Wywoływanie wycieków pamięci na potrzeby testowania

Aby przeanalizować wykorzystanie pamięci, wyróżnij kod aplikacji i spróbuj wymusić pamięć. wyciek danych. Jednym ze sposobów na wywołanie wycieku pamięci w aplikacji jest pozostawienie jej na pewien czas zanim sprawdzisz stertę. Wycieki mogą się przenosić do góry alokacji w pniu. Im mniejszy wyciek, tym dłużej trzeba uruchamiać aplikację, aby go zobaczyć.

Wyciek pamięci możesz też wywołać na jeden z tych sposobów:

  • Wielokrotnie obróć urządzenie z pionowej na poziomą i z powrotem w różnych stanach aktywności. Obrócenie urządzenia często powoduje wyciek obiektu Activity, Context lub View, ponieważ system ponownie tworzy obiekt Activity, a jeśli aplikacja zawiera odwołanie do jednego z tych obiektów gdzie indziej, system nie może go usunąć.
  • Przełączanie się między aplikacją i inną aplikacją w różnych stanach aktywności. Możesz na przykład przejść na ekran główny, a potem wrócić do aplikacji.

Eksportowanie i importowanie zapisu zrzutu stosu

Możesz eksportować i importować plik z zrzutem stosu na karcie Wcześniejsze nagrania w profilu. Android Studio zapisuje i nagrasz je jako plik .hprof.

Możesz też użyć innego narzędzia do analizowania plików w usłudze .hprof, takiego jak jhat, musisz przekonwertować plik .hprof z formatu Androida na Java SE Format pliku: .hprof. Aby przekonwertować format pliku, użyj narzędzia hprof-conv znajdziesz w katalogu {android_sdk}/platform-tools/. Uruchom polecenie hprof-conv z 2 argumentami: pierwotną nazwą pliku .hprof i lokalizacją, w której ma zostać zapisany przekonwertowany plik .hprof, w tym nowa nazwa pliku .hprof. Na przykład:

hprof-conv heap-original.hprof heap-converted.hprof