Rejestrowanie alokacji w językach Java i Kotlin pomaga identyfikować niepożądane wzorce pamięci, które mogą powodować problemy z wydajnością. Profiler może wyświetlać te informacje o alokacjach obiektów:
- Jakie typy obiektów zostały przydzielone i ile miejsca zajmują.
- Ślad stosu każdej alokacji, w tym wątek, w którym została wykonana.
- Czas zwolnienia obiektów.
Rejestruj przydziały pamięci podczas normalnych i ekstremalnych interakcji użytkownika, aby dokładnie określić, w którym miejscu kod przydziela zbyt wiele obiektów w krótkim czasie lub przydziela obiekty, które stają się wyciekami. Dowiedz się więcej o tym, dlaczego warto profilować pamięć aplikacji
Jak rejestrować alokacje Java/Kotlin
Aby zarejestrować alokacje w języku Java/Kotlin, wybierz zadanie Śledź zużycie pamięci (alokacje w języku Java/Kotlin) na karcie Główna profilera. Pamiętaj, że do rejestrowania alokacji w językach Java i Kotlin potrzebujesz aplikacji z możliwością debugowania (użyj opcji Profiler: run 'app' as debuggable (complete data)).
Android Studio domyślnie rejestruje wszystkie alokacje obiektów w pamięci. Jeśli masz aplikację, która przydziela dużo obiektów, podczas profilowania możesz zauważyć widoczne spowolnienia. Aby zwiększyć wydajność podczas profilowania, w menu Śledzenie alokacji wybierz Próbkowane zamiast Pełne. Podczas próbkowania profiler zbiera alokacje obiektów w pamięci w regularnych odstępach czasu.
Aby wymusić zdarzenie odzyskiwania pamięci podczas nagrywania, kliknij ikonę kosza .
Omówienie alokacji w Javie i Kotlinie
Po zatrzymaniu nagrywania zobaczysz:
- Oś czasu zdarzeń pokazuje stany aktywności, zdarzenia związane z działaniami użytkownika i zdarzenia związane z obracaniem ekranu.
- Oś czasu wykorzystania pamięci zawiera te informacje. Aby filtrować według określonego zakresu czasu, wybierz część osi czasu.
- Wykres słupkowy pokazujący ilość pamięci wykorzystywanej przez poszczególne kategorie pamięci, co jest wskazane na osi Y po lewej stronie i w legendzie kolorów u góry.
- Linia przerywana wskazuje liczbę przydzielonych obiektów, co jest widoczne na osi Y po prawej stronie.
- Ikona każdego zdarzenia odśmiecania.
- Na karcie Tabela wyświetla się lista zajęć. Łączna liczba to liczba alokacji na końcu wybranego zakresu czasu (Alokacje minus Dealokacje), więc warto najpierw debugować klasy o najwyższych wartościach Łącznej liczby. Jeśli bardziej interesuje Cię rozwiązywanie problemów z zajęciami na podstawie maksymalnych przydziałów w wybranym zakresie czasu, posortuj je według przydziałów. Podobnie pozostały rozmiar to rozmiar przydzielonych zasobów pomniejszony o rozmiar zwolnionych zasobów w bajtach.
- Gdy klikniesz klasę na liście Tabela, otworzy się panel Instancja z listą powiązanych obiektów, w tym z informacjami o tym, kiedy zostały przydzielone i zwolnione, oraz o ich rozmiarze płytkim.
Karta Wizualizacja pokazuje zbiorczy widok wszystkich obiektów w stosie wywołań w wybranym zakresie czasu. Pokazuje ona, ile pamięci zajmuje stos wywołań z wyświetlonymi instancjami. Pierwszy wiersz zawiera nazwę wątku. Domyślnie obiekty są ułożone od lewej do prawej na podstawie rozmiaru przydzielonego miejsca. Aby zmienić kolejność, użyj menu.
Użyj menu, aby odfiltrować określone obszary. Oprócz filtrów dostępnych podczas przechwytywania zrzutu pamięci możesz filtrować klasy w pamięci JNI, czyli w pamięci, która pokazuje, gdzie są przydzielane i zwalniane odwołania do interfejsu Java Native Interface (JNI).
W menu wybierz sposób rozmieszczenia przydziałów. Oprócz ustawień dostępnych podczas przechwytywania zrzutu pamięci możesz też sortować według stosu wywołań.
Sposób zliczania pamięci
Liczby widoczne u góry są oparte na wszystkich stronach pamięci prywatnej, które zostały przydzielone aplikacji zgodnie z systemem Android. Ta liczba nie obejmuje stron udostępnionych systemowi ani innym aplikacjom. Kategorie w liczbie pamięci są następujące:
- Java: pamięć z obiektów przydzielonych z kodu Java lub Kotlin.
Natywna: pamięć z obiektów przydzielonych z kodu C lub C++.
Nawet jeśli nie używasz w aplikacji języka C++, możesz tu zobaczyć użycie pamięci natywnej, ponieważ framework Androida używa jej do obsługi różnych zadań w Twoim imieniu, np. podczas obsługi zasobów obrazów i innych grafik – nawet jeśli napisany przez Ciebie kod jest w języku Java lub Kotlin.
Grafika: pamięć używana na potrzeby kolejek buforów graficznych do wyświetlania pikseli na ekranie, w tym powierzchni GL, tekstur GL i innych elementów. Pamiętaj, że jest to pamięć współdzielona z procesorem, a nie dedykowana pamięć GPU.
Stos: pamięć używana przez stosy natywne i Java w aplikacji. Zwykle jest to związane z liczbą wątków uruchomionych w aplikacji.
Kod: pamięć używana przez aplikację na potrzeby kodu i zasobów, np. kodu bajtowego DEX, zoptymalizowanego lub skompilowanego kodu DEX.
so
biblioteki i czcionki.Inne: pamięć używana przez aplikację, której system nie potrafi sklasyfikować.
Przydzielone: liczba obiektów Java/Kotlin przydzielonych przez aplikację. Nie obejmuje to obiektów przydzielonych w C ani C++.
Sprawdzanie rekordu alokacji
Aby sprawdzić rekord przydziału, wykonaj te czynności:
- Przejrzyj listę klas na karcie Tabela, aby znaleźć obiekty o niezwykle dużych wartościach Przydziały lub Łączna liczba (w zależności od tego, co optymalizujesz), które mogą być wyciekłe.
- W panelu Widok instancji kliknij instancję. W zależności od tego, co ma zastosowanie w danym przypadku, otworzy się karta Pola lub Stos wywołań alokacji. Skorzystaj z informacji na kartach Pola lub Stos wywołań alokacji, aby sprawdzić, czy instancje są rzeczywiście potrzebne, czy są niepotrzebnymi duplikatami.
Kliknij prawym przyciskiem myszy dowolny wpis na liście, aby przejść do odpowiedniego kodu źródłowego.
Wyświetlanie globalnych odwołań JNI
Java Native Interface (JNI) to platforma, która umożliwia wzajemne wywoływanie kodu Java i kodu natywnego. Odwołania JNI są zarządzane ręcznie przez kod natywny, więc mogą wystąpić problemy, takie jak:
- Obiekty Java używane przez kod natywny są zbyt długo utrzymywane przy życiu.
- Niektóre obiekty w stercie Javy mogą stać się niedostępne, jeśli odwołanie JNI zostanie odrzucone bez wcześniejszego usunięcia.
- Wykorzystano limit globalnych odwołań JNI.
Aby rozwiązać takie problemy, w profilerze wybierz View JNI heap (Wyświetl stertę JNI), aby przejrzeć wszystkie globalne odwołania JNI i odfiltrować je według typów Java i natywnych stosów wywołań. Kliknij prawym przyciskiem myszy pole instancji na karcie Pola i wybierz Przejdź do instancji, aby wyświetlić odpowiedni stos wywołań alokacji.
Karta Stos wywołań alokacji pokazuje, gdzie w kodzie są przydzielane i zwalniane odwołania JNI.
Więcej informacji o JNI znajdziesz w wskazówkach dotyczących JNI.