Typy profili i ich zastosowania

Na Androidzie możesz nagrywać kilka rodzajów profili wydajności. Zbieranie profilu pomaga w rozwiązywaniu problemów związanych z szybkością działania aplikacji, ilością wykorzystywanej pamięci, zużyciem energii i innymi kwestiami.

W tym dokumencie opisujemy najbardziej przydatne typy profili i kiedy ich używać do rozwiązywania typowych problemów z wydajnością.

Ślady systemu

Przykład śledzenia systemu
Rysunek 1. Przykład śledzenia systemu.

Ślad systemowy to zaawansowany profil, który zawiera informacje o procesach, wątkach, czasie, wykonywaniu zadań i procesora oraz o zdarzeniach systemowych lub zdefiniowanych przez użytkownika.

Z perspektywy aplikacji informacje w śladach mogą obejmować szeroki zakres obszarów, w tym opóźnienia, zacinanie się, pamięć, baterię i inne.

Ślady systemowe zawierają te zdarzenia wywoływane przez kod, które mogą być zdefiniowane przez system lub użytkownika. Zdarzenia wywoływane przez kod to zdarzenia, które użytkownicy mogą wywoływać za pomocą wywołań funkcji.

  • Fragmenty śladu: przedstawiają czas między różnymi punktami w kodzie. Można je dodawać za pomocą interfejsów API Trace.beginSectionTrace.endSection.
  • Liczniki śledzenia: wartości liczbowe reprezentujące dane, np. rozmiar sterty. Można je dodawać za pomocą interfejsu Trace.setCounter API.

Ślady systemowe zawierają też dane, które można tworzyć na podstawie zapytań PerfettoSQL i wykorzystywać do przeprowadzania analiz lub porównywania śladów.

Zalecamy używanie śladów systemowych do wykonywania tych zadań:

  • Diagnozowanie problemów z opóźnieniami. Ślady systemowe doskonale nadają się do wykrywania problemów z opóźnieniami spowodowanych przez opóźnienia, oczekiwanie lub problemy z planowaniem. Inne profilerzy, np. profilerzy opartych na próbkach, nie dostarczają informacji o czasie, które są dostępne w przypadku śledzenia systemu.

  • Znajdź zduplikowane obliczenia. Śledzenie może ujawnić, czy niektóre obliczenia są powtarzane, co może wskazywać na niepotrzebne operacje.

  • Diagnozowanie problemów z rywalizacją o blokadę. Dzięki informacjom o stanach wątków i wykresom pokazującym, kiedy zasoby są blokowane, możesz sprawdzić, czy blokady (np. blokady synchronized) powodują opóźnienia w działaniach użytkowników.

  • Poznaj wielowątkowość w swojej aplikacji. Ślady oferują widok wielu wątków, pokazując stan każdego z nich oraz wszelkie wycinki śladu dodane przez system lub aplikację. Ten widok wielowątkowy pomaga zrozumieć, które wątki są aktywne, które są w stanie uśpienia, co wykonują i jak ze sobą współdziałają.

  • Przeprowadzaj złożone analizy skuteczności. Dzięki zaawansowanemu interfejsowi użytkownika i możliwości wyświetlania różnych typów informacji ślady systemowe są przydatne do debugowania wielu problemów z wydajnością, w tym opóźnień, wykorzystania pamięci i baterii.

Ślady systemowe obsługują też zapytania w języku PerfettoSQL. Ta zaawansowana funkcja umożliwia:

  • wyodrębniać określone dane,
  • Przekształcanie danych śledzenia w rodzaje danych niestandardowych.
  • Twórz ścieżki debugowania z zapytań, aby łatwiej wizualizować w interfejsie Perfetto to, co jest dla Ciebie najważniejsze.
  • Przeprowadzaj złożone analizy bezpośrednio w interfejsie Perfetto.

Profile próbek stosu

Przykładowy profil próbki stosu
Rysunek 2. Przykładowy profil próbki stosu.

Profile stosu działają poprzez rejestrowanie próbek wykonywania kodu i przechowywanie informacji o stosie wywołań z określoną częstotliwością, gdy wątek wykonuje zadania na procesorze. Dzięki temu możesz dowiedzieć się, co robi Twój kod podczas wykonywania.

Zalecamy używanie próbek stosu do wykonywania tych czynności:

  • Zoptymalizuj aktywne punkty. Próbki stosu pomagają identyfikować części kodu, w których występuje duża aktywność procesora, co oznacza, że wątek jest często w stanie „uruchomiony”.
  • Zrozumienie wykonywania kodu Próbki stosu mogą pomóc w zrozumieniu ogólnego działania bazy kodu.
  • Określ kod, który nie powinien być uruchamiany. Możesz znaleźć stosy wywołań, które w ogóle nie powinny być uruchamiane, co wskazuje na natychmiastowe możliwości optymalizacji.

Zrzuty sterty

Przykład zrzutu stosu
Rysunek 3. Przykład zrzutu stosu.

Zrzuty sterty Javy pokazują obraz pamięci sterty Javy aplikacji. Ten zrzut zawiera wszystkie obiekty i informacje o tym, jak się do siebie odnoszą w momencie utworzenia zrzutu.

Zalecamy zbieranie zrzutów sterty, aby:

  • Odkrywanie zduplikowanych obiektów Zrzuty sterty pokazują liczbę aktywnych obiektów, co jest przydatne do śledzenia zduplikowanych obiektów. Zawierają też odwołania do obiektów, które pomagają określić lokalizację kodu, w której zostały utworzone.
  • Znajdowanie wycieków pamięci Zrzuty sterty mogą ujawniać pamięć, która w momencie wykonania zrzutu nie powinna być już używana, co wskazuje na potencjalne wycieki pamięci.
  • Identyfikowanie obiektów, które można zoptymalizować. Zrzuty sterty pokazują obiekty, które zużywają dużo pamięci, oraz ich liczbę, co pomaga identyfikować nieefektywne wzorce wykorzystania pamięci.

Profile sterty

Przykład profilu sterty
Rysunek 4. Przykład profilu sterty.

Profile sterty są dostępne w wersjach natywnej i Java. Doskonale nadają się do debugowania problemów z pamięcią. Są one podobne do próbek stosu wywołań, ale zamiast mierzyć cykle procesora, pobierają próbki, gdy przydzielana jest pamięć.

Zalecamy używanie profili sterty do wykonywania tych czynności:

  • Zmniejsz fragmentację pamięci. Profile sterty zawierają próbki z lokalizacjami kodu dla alokacji pamięci. Pomaga to identyfikować obszary, w których powstaje wiele obiektów tymczasowych, co może przyczyniać się do częstego odśmiecania pamięci (GC) w aplikacji.
  • Wykrywaj wycieki pamięci. Profile sterty można używać z innymi profilami pamięci do diagnozowania i usuwania wycieków pamięci. Pomagają one wskazywać miejsca, które przydzielają znacznie więcej pamięci niż oczekiwano.

Łączenie profili

Często analizujesz wyniki za pomocą jednego profilu. Jednak zebranie wielu profili lub jednego połączonego profilu może często dać pełniejszy obraz i pomóc w diagnozowaniu złożonych problemów, których nie można wykryć za pomocą jednego profilu.

Oto scenariusze, w których łączenie profili jest korzystne:

  • Scenariusz 1.Badanie kodu bez instrumentacji Ślad systemowy może pokazywać opóźnienia w przypadku operacji, które zostały już przez Ciebie zinstrumentowane. Może jednak potrzebujesz więcej informacji o nieinstrumentowanych częściach kodu, które są uruchamiane w tym czasie. Aby to sprawdzić, utwórz profil stosu wywołań, aby poznać wykonywany kod. Te informacje pomogą Ci ulepszyć śledzenie przez dodanie większej liczby wycinków śledzenia.

  • Scenariusz 2. Analizowanie wycieków pamięci i odzyskiwania pamięci. Załóżmy, że ślad systemowy pokazuje stały wzrost pamięci sterty Javy z powodu alokacji, co powoduje częste odśmiecanie pamięci. Aby poznać przydzielone obiekty, utwórz profil sterty lub zrzut sterty. To połączone podejście pomoże Ci znaleźć sposoby na zmniejszenie zużycia pamięci. Na przykład zmniejszenie marnotrawnego lub optymalizowalnego przydziału pamięci za pomocą buforowania może zapobiec występowaniu odśmiecania pamięci.