Przykłady pomiarów i analiz skuteczności

Te przykłady pokazują, jak korzystać z śledzenia systemu za pomocą Macroporównania, wraz z profilowaniem pamięci, aby mierzyć i poprawiać określone rodzaje problemów z wydajnością.

Debugowanie uruchamiania aplikacji za pomocą systrace

Do debugowania czasu uruchamiania zalecamy użycie logów systrace. Systrace to system, który używa wstępnie opracowanego kodu do zwracania czasu na realizację określonych zdarzeń. Dzięki tym śladom możesz zobaczyć, co dzieje się w aplikacji, a nawet w innych procesach w systemie. Biblioteki platformy Androida i biblioteki Jetpack wykorzystują wiele kluczowych zdarzeń w aplikacji i są odpowiednio rejestrowane. Możesz również dodać do aplikacji własne logi czasu, które będą widoczne w tych samych narzędziach do wizualizacji Systrace, aby dać ogólny obraz tego, co wydarzyło się w aplikacji.

Użycie systrace lub Perfetto

Aby dowiedzieć się więcej o podstawowym wykorzystaniu protokołu systrace, obejrzyj ten film: Debugging Application Performance (Debugowanie wydajności aplikacji).

Aby analizować czas uruchamiania, musisz najpierw zrozumieć, co się dzieje podczas uruchamiania. Jeśli potrzebujesz więcej informacji niż te opisane na tej stronie, zapoznaj się z dokumentacją dotyczącą czasu uruchamiania aplikacji, w której znajdziesz omówienie procesu uruchamiania aplikacji.

Etapy uruchamiania aplikacji:

  • Uruchamianie procesu
  • Inicjowanie obiektów aplikacji ogólnych
  • Utwórz i zainicjuj działanie
  • Ulepsz układ
  • Narysuj pierwszą klatkę

Typy startupów obejmują następujące etapy:

  • Uruchomienie „na zimno”: ma miejsce, gdy aplikacja jest uruchamiana po raz pierwszy od uruchomienia lub po zakończeniu procesu aplikacji (przez użytkownika lub system). Startup tworzy nowy proces bez zapisanego stanu.
  • Uruchomienie z pamięci: ma miejsce, gdy aplikacja działa już w tle, ale działanie musi zostać odtworzone i przeniesione na pierwszy plan. Aktywność jest odtworzona podczas ponownego procesu z użyciem istniejącego procesu lub proces jest odtworzony z zapisanym stanem. Biblioteka testów Macroporównawczy obsługuje spójne testy uruchamiania częściowo z pamięci za pomocą pierwszej opcji.
  • Uruchomienie z pamięci: ma miejsce, gdy proces i działanie są nadal uruchomione i tylko trzeba przenieść je na pierwszy plan, np. w razie potrzeby odtworzyć niektóre obiekty lub renderować nową aktywność na pierwszym planie. To najkrótszy scenariusz startupów.

Zalecamy przechwytywanie systracs za pomocą działającej na urządzeniu aplikacji do śledzenia systemu dostępnej w Opcji programisty. Jeśli chcesz korzystać z narzędzi wiersza poleceń, możesz używać narzędzia Perfetto na Androidzie 10 (poziom interfejsu API 29) i nowszym. Urządzenia we wcześniejszych wersjach powinny używać polecenia systrace.

Pamiętaj, że termin „pierwsza klatka” jest nieco mylący, ponieważ po utworzeniu początkowej aktywności aplikacje mogą znacznie się różnić w zakresie obsługi uruchamiania. Niektóre aplikacje będą dalej inflować przez kilka klatek, a inne od razu uruchamiają się jako dodatkowe działanie.

Jeśli to możliwe, zalecamy dodanie wywołania reportFullyDrawn (dostępnego w Androidzie 10 i nowszych) podczas uruchamiania z perspektywy aplikacji.

Oto kilka rzeczy, na które należy zwrócić uwagę w tych logach czasu systemu:

Monitorowanie rywalizacji
Rysunek 1. Konkurencja w zakresie zasobów chronionych monitorowaniem może spowodować znaczne opóźnienie w uruchamianiu aplikacji.

Synchroniczne transakcje segregujące
Rysunek 2. Poszukaj niepotrzebnych transakcji na ścieżce krytycznej aplikacji.

Równoczesne czyszczenie pamięci
Rysunek 3. Równoczesne usuwanie czyszczenia pamięci jest powszechne i ma stosunkowo niewielki wpływ, ale jeśli często je nakładasz, rozważ zbadanie tego problemu przy użyciu programu do profilowania pamięci w Android Studio.

Wejście-wyjście przy uruchamianiu
Rysunek 4. Sprawdzaj wejścia/wyjścia podczas uruchamiania i szukaj dłuższych przerw.

Na ilustracji 4 warto zwrócić uwagę, że inne procesy wykonujące w tym samym czasie operacje wejścia-wyjścia mogą powodować rywalizację wejścia-wyjścia, dlatego upewnij się, że inne procesy nie działają.

Znaczna aktywność w innych wątkach może zakłócać działanie wątku UI, dlatego podczas uruchamiania zwróć uwagę na pracę w tle. Pamiętaj, że urządzenia mogą mieć różne konfiguracje procesora, więc liczba wątków, które można uruchomić równolegle, może się różnić w zależności od urządzenia.

Zapoznaj się też z przewodnikiem dotyczącym typowych źródeł zacięć

Użyj narzędzia do profilowania pamięci w Android Studio

Program profilujący pamięci w Android Studio to zaawansowane narzędzie do zmniejszenia wykorzystania pamięci, które może być spowodowane wyciekami pamięci lub nieprawidłowymi wzorcami jej wykorzystania. Udostępnia widok na żywo przydziałów i kolekcji obiektów.

Aby rozwiązać problemy z pamięcią w aplikacji, możesz użyć programu profilu pamięci do śledzenia przyczyn i częstotliwości odśmiecania pamięci, a także tego, czy są możliwe wycieki pamięci powodujące ciągłe zwiększanie stosu.

Profilowanie pamięci aplikacji dzieli się na te etapy:

1. Wykrywanie problemów z pamięcią

Aby wykryć problemy z pamięcią, zacznij od zarejestrowania sesji profilowania pamięci aplikacji. Następnie wyszukaj obiekt, którego ilość pamięci rośnie, aby w końcu aktywować zdarzenie czyszczenia pamięci.

Zwiększam liczbę obiektów
Rysunek 5. Program profilujący pamięci pokazujący większe przydziały obiektów w miarę upływu czasu.

Wywóz śmieci
Rysunek 6. Program profilujący pamięci wyświetlający zdarzenia czyszczenia pamięci.{.:image-caption}

Gdy znajdziesz przypadek użycia, który zwiększa presję pamięciową, rozpocznij analizę pod kątem głównych przyczyn.

2. Diagnozowanie problematycznych obszarów pamięci

Wybierz zakres na osi czasu, aby wizualizować zarówno przydziały, jak i mały rozmiar.

Wizualizacja przydziałów i małego rozmiaru
Rysunek 7. Program do profilowania pamięci pokazujący przydziały i rozmiary wybranego zakresu na osi czasu.

Dane te możesz sortować na kilka sposobów. W sekcjach poniżej znajdziesz przykłady tego, jak każdy z widoków może pomóc w analizowaniu problemów.

Rozmieść według zajęć

Organizowanie według klas jest przydatne, gdy szukasz klas generujących obiekty, które powinny być przechowywane w pamięci podręcznej lub ponownie wykorzystywane z puli pamięci.

Wyobraźmy sobie np. aplikację, która co sekundę tworzy 2000 obiektów klasy o nazwie „Vertex”. Spowoduje to zwiększenie liczby przydziałów o 2000 na sekundę i będzie widoczne przy sortowaniu według klasy. Czy takie obiekty należy wykorzystywać ponownie, aby uniknąć generowania tych odpadów? Jeśli odpowiedź brzmi „tak”, prawdopodobnie konieczne będzie wdrożenie puli pamięci.

Uporządkuj według stosu wywołań

Alokacja według stosu wywołań jest przydatna, gdy istnieje gorąca ścieżka, w której przydzielana jest pamięć, na przykład w pętli lub konkretna funkcja wykonująca dużo zadań alokacji. Dzięki temu możesz zobaczyć te hotspoty alokacji.

Rozmiar płytki lub zachowany

Opcja „Płytki rozmiar” śledzi tylko pamięć obiektu, dlatego najbardziej przydatna do śledzenia prostych klas złożonych z głównie obiektów podstawowych.

Zachowany rozmiar to łączna ilość pamięci przydzielona bezpośrednio przez obiekt, a także inne przydzielone obiekty, do których obiekt się odwołuje. Jest przydatna do śledzenia wykorzystania pamięci ze względu na złożone obiekty, które wymagają przydziału innych obiektów, a nie tylko pól podstawowych. Aby uzyskać tę wartość, utwórz zrzut pamięci za pomocą programu do profilowania pamięci. Obiekty przydzielone na tej stercie zostaną dodane do wyświetlacza.

Pełny zrzut pamięci
Rysunek 8. Zrzut pamięci możesz utworzyć w każdej chwili, klikając przycisk zrzutu Java sterta na pasku narzędzi programu do profilowania pamięci.

dodano jako kolumnę
Rysunek 9. Utworzenie zrzutu pamięci powoduje wyświetlenie kolumny przedstawiającej przydziały obiektów na stercie.

3. Pomiar wpływu optymalizacji

Jednym z ulepszeń w zakresie optymalizacji pamięci, który można łatwo zmierzyć, jest zbieranie śmieci. Gdy optymalizacja zmniejsza wykorzystanie pamięci, zmniejsza się liczbę odśmieconych pamięci (GC). Aby to zmierzyć, zmierz czas między GC na osi czasu programu profilującego. Po zakończeniu optymalizacji pamięci powinny pojawić się dłuższe czasy trwania między GC.

Najważniejsze korzyści z poprawek pamięci to:

  • Aplikacja będzie zamykana rzadziej z powodu braku pamięci, jeśli nie występuje w niej stale wolne miejsce w pamięci.
  • Mniejsza liczba GC poprawia wskaźniki zacięć. Dzieje się tak, ponieważ algorytmy GC powodują rywalizację z CPU, co może doprowadzić do wstrzymywania zadań renderowania podczas ich wykonywania.