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 Activity
i Fragment
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łowegoFragmentManager
, 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 ramachFragmentTransaction
.
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 konteneraActivity
lubContext
. - 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
lubView
, ponieważ system ponownie tworzy obiektActivity
, 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