Okno Logcat w Android Studio wyświetla komunikaty systemowe, takie jak wystąpienie garbagecollection, oraz komunikaty dodane do aplikacji za pomocą klasy Log
. Wyświetla komunikaty w czasie rzeczywistym i zachowuje historię, dzięki czemu można przeglądać starsze komunikaty.
Aby wyświetlać tylko interesujące nas informacje, można tworzyć filtry, modyfikować ilość informacji wyświetlanych w komunikatach, ustawiać poziomy priorytetu, wyświetlać komunikaty tworzone tylko przez kod aplikacji i przeszukiwać dziennik. Domyślnie logcats wyświetla tylko dane wyjściowe dziennika związane z ostatnio uruchomioną aplikacją.
Gdy aplikacja rzuca wyjątek, logcat pokazuje komunikat, po którym następuje powiązany ślad stosu zawierający odnośniki do linii kodu.
Od Android Studio 2.2, okno Uruchom również wyświetla komunikaty dziennika dla aktualnie uruchomionej aplikacji. Zauważ, że możesz skonfigurować wyświetlanie wyjścia logcat, ale nie okna Uruchom.
Zobacz logi swojej aplikacji
Aby wyświetlić logi dla aplikacji:
- Zbuduj i uruchom swoją aplikację na urządzeniu.
- Kliknij przycisk Widok > Okna narzędziowe > Logcat (lub kliknij przycisk Logcat na pasku okien narzędziowych).
W oknie Logcat wyświetlane są komunikaty dziennika dla wybranej aplikacji, wybrane z list rozwijanych w górnej części okna, jak pokazano na rysunku 1.
Rysunek 1. Okno programu logcat
Domyślnie program logcat wyświetla tylko komunikaty dziennika aplikacji uruchomionej na urządzeniu. Aby zmienić to ustawienie domyślne, zobacz, jak filtrować komunikaty logcat.
Pasek narzędzi logcat zawiera następujące przyciski:
- Wyczyść logcat : Kliknij, aby wyczyścić widoczny dziennik.
- Przewiń do końca : Kliknij, aby przeskoczyć do dolnej części dziennika i zobaczyć najnowsze komunikaty dziennika. Jeśli następnie klikniesz wiersz w dzienniku, widok wstrzymuje przewijanie w tym punkcie.
- W górę śladu stosu i W dół śladu stosu : Kliknij, aby poruszać się w górę i w dół śladów stosu w dzienniku, wybierając kolejne nazwy plików (i przeglądając odpowiadające im numery linii w edytorze), które pojawiają się w wydrukowanych wyjątkach. Jest to takie samo zachowanie, jak po kliknięciu nazwy pliku w dzienniku.
- Użyj miękkich zawijasów : Kliknij, aby włączyć zawijanie wierszy i zapobiec przewijaniu w poziomie (choć wszelkie niełamliwe ciągi nadal będą wymagały przewijania w poziomie).
- Drukuj : Kliknij, aby wydrukować komunikaty logcat. Po wybraniu preferencji drukowania w wyświetlonym oknie dialogowym można również wybrać opcję zapisania w pliku PDF.
- Uruchom ponownie : Kliknij, aby wyczyścić dziennik i ponownie uruchomić program logcat. W przeciwieństwie do przycisku Wyczyść logcat, to odzyskuje i wyświetla poprzednie wiadomości dziennika, więc jest najbardziej przydatne, jeśli Logcat staje się niereagujący i nie chcesz stracić wiadomości dziennika.
- Nagłówek logcat : Kliknij, aby otworzyć okno dialogowe Konfiguruj nagłówek logcat, w którym można dostosować wygląd każdego komunikatu logcat, np. czy pokazywać datę i godzinę.
- Zrzut ekranu : Kliknij, aby przechwycić zrzut ekranu.
- Nagrywanie ekranu : Kliknij, aby nagrać wideo urządzenia (maksymalnie przez 3 minuty).
Wpisywanie komunikatów dziennika
Klasa Log
umożliwia tworzenie komunikatów dziennika, które pojawiają się w logcat. Ogólnie rzecz biorąc, powinieneś używać następujących metod dziennika, wymienionych w kolejności od najwyższego do najniższego priorytetu (lub od najmniej do najbardziej dosłownego):
-
Log.e(String, String)
(error) -
Log.w(String, String)
(warning) -
Log.i(String, String)
(information) -
Log.d(String, String)
(debug) -
Log.v(String, String)
(verbose)
Zobacz opis klasy Log
, aby zapoznać się z pełniejszą listą opcji.
Nie powinieneś nigdy kompilować logów verbose do swojej aplikacji, chyba że podczas jej rozwoju. Dzienniki debugowania są kompilowane, ale usuwane w czasie działania, podczas gdy dzienniki błędów, ostrzeżeń i informacji są zawsze zachowywane.
Dla każdej metody dziennika, pierwszym parametrem powinien być unikalny znacznik, a drugim parametrem jest komunikat. Znacznik komunikatu dziennika systemowego to krótki łańcuch wskazujący składnik systemu, z którego pochodzi komunikat (na przykład ActivityManager
). Twój znacznik może być dowolnym łańcuchem, który uznasz za pomocny, takim jak nazwa bieżącej klasy.
Dobrą konwencją jest zadeklarowanie w swojej klasie stałej TAG
do wykorzystania w pierwszym parametrze. Na przykład, możesz utworzyć komunikat logu informacyjnego w następujący sposób:
Kotlin
private const val TAG = "MyActivity"...Log.i(TAG, "MyClass.getView() — get item number $position")
Java
private static final String TAG = "MyActivity";...Log.i(TAG, "MyClass.getView() — get item number " + position);
Uwaga: Nazwy znaczników większe niż 23 znaki są obcinane na wyjściu logcat.
Format komunikatu logcat
Każdy komunikat dziennika systemu Android ma przypisany znacznik i priorytet. Znacznik systemowego komunikatu dziennika to krótki łańcuch wskazujący komponent systemowy, z którego pochodzi komunikat (na przykład ActivityManager
). Znacznik zdefiniowany przez użytkownika może być dowolnym ciągiem znaków, który użytkownik uzna za pomocny, na przykład nazwą bieżącej klasy (zalecany znacznik). Definiujesz go w wywołaniu metody Log
, na przykład:
Kotlin
Log.d(tag, message)
Java
Log.d(tag, message);
Priorytet jest jedną z następujących wartości:
- V: Verbose (najniższy priorytet)
- D: Debug
- I: Info
- W: Warning
- E: Error
- A: Assert
Format komunikatu dziennika to:
date time PID-TID/package priority/tag: message
Na przykład poniższy komunikat dziennika ma priorytet V
i znacznik AuthZen
:
12-10 13:02:50.071 1901-4229/com.google.android.gms V/AuthZen: Handling delegate intent.
PID oznacza identyfikator procesu, a TID to identyfikator wątku; mogą być takie same, jeśli istnieje tylko jeden wątek.
Ustaw poziom dziennika
Możesz kontrolować, ile wiadomości pojawia się w logcat, ustawiając poziom dziennika. Możesz wyświetlać wszystkie komunikaty lub tylko te, które wskazują na najpoważniejsze warunki.
Pamiętaj, że logcat nadal zbiera wszystkie komunikaty niezależnie od ustawienia poziomu dziennika. Ustawienie to określa jedynie, co logcat wyświetla.
W menu Poziom dziennika wybierz jedną z następujących wartości:
- Verbose: Pokaż wszystkie komunikaty dziennika (wartość domyślna).
- Debug: Pokaż komunikaty dziennika debugowania, które są przydatne tylko podczas opracowywania, a także poziomy komunikatów niższe na tej liście.
- Info: Pokaż oczekiwane komunikaty dziennika dla regularnego użytkowania, jak również poziomy komunikatów niższe na tej liście.
- Warn: Pokaż możliwe problemy, które nie są jeszcze błędami, jak również poziomy komunikatów niższe na tej liście.
- Błąd: Pokaż problemy, które spowodowały błędy, jak również poziom komunikatu niższy na tej liście.
- Asercja: Pokaż problemy, które zgodnie z oczekiwaniami programisty nigdy nie powinny wystąpić.
Wyszukiwanie komunikatów logcat
Aby przeszukać komunikaty aktualnie wyświetlane w logcat:
- Opcjonalnie wybierz opcję Regex, jeśli chcesz użyć wzorca wyszukiwania wyrażenia regularnego.
- Wpisz ciąg znaków w polu wyszukiwania .
Wyświetlacz wyjścia logcat zmienia się odpowiednio.
- Naciśnij Enter, aby zapisać ciąg wyszukiwania w menu podczas tej sesji.
- Aby powtórzyć wyszukiwanie, wybierz je z menu wyszukiwania. Wybierz lub usuń zaznaczenie opcji Regex w razie potrzeby (ustawienie nie jest zapamiętywane).
Filtrowanie komunikatów logcat
Jednym ze sposobów zredukowania wyjścia dziennika do możliwego do opanowania poziomu jest ograniczenie go za pomocą filtru.
Uwaga: Filtr dotyczy całej historii logcat, a nie tylko komunikatów aktualnie wyświetlanych w logcat. Upewnij się, że inne opcje wyświetlania są odpowiednio ustawione, aby można było zobaczyć dane wyjściowe filtru, które chcesz zbadać.
Aby zdefiniować i zastosować filtr:
- W menu filtru wybierz opcję filtru:
- Pokaż tylko wybraną aplikację: Wyświetlaj komunikaty tworzone tylko przez kod aplikacji (domyślnie). Program Logcat filtruje komunikaty dziennika przy użyciu identyfikatora PID aktywnej aplikacji.
- Bez filtrów: Zastosuj brak filtrów. Logcat wyświetla wszystkie komunikaty dziennika z urządzenia, niezależnie od tego, który proces został wybrany.
- Edytuj konfigurację filtrów: Utwórz lub zmodyfikuj filtr niestandardowy. Na przykład, można utworzyć filtr, aby wyświetlić komunikaty dziennika z dwóch aplikacji w tym samym czasie.
Po zdefiniowaniu filtrów można je również wybrać w menu. Aby usunąć je z menu, usuń je.
- Jeśli wybrano opcję Edytuj konfigurację filtra, utwórz lub zmodyfikuj filtr:
- Określ parametry filtru w oknie dialogowym Utwórz nowy filtr logcat:
- Nazwa filtra: Wpisz nazwę filtru, który chcesz zdefiniować, lub wybierz go w lewym okienku, aby zmodyfikować istniejący filtr. Nazwa może zawierać tylko małe litery, znaki podkreślenia i cyfry.
- Znacznik logu: Opcjonalnie można określić znacznik. Aby uzyskać więcej informacji, zobacz temat Format komunikatu logcat.
- Komunikat dziennika: Opcjonalnie określ tekst komunikatu dziennika. Aby uzyskać więcej informacji, zobacz Format komunikatu logcat.
- Nazwa pakietu: Opcjonalnie określ nazwę pakietu. Aby uzyskać więcej informacji, zobacz Format komunikatu logcat.
- PID: Opcjonalnie określ identyfikator procesu. Aby uzyskać więcej informacji, zobacz Format komunikatu logcat.
- Poziom dziennika: Opcjonalnie wybierz poziom dziennika. Aby uzyskać więcej informacji, zobacz temat Ustawianie poziomu dziennika.
- Regex: Wybierz tę opcję, aby użyć składni wyrażenia regularnego dla tego parametru.
- Kliknij przycisk +, aby dodać definicję filtru do lewego okienka.
Aby usunąć filtr, zaznacz go w lewym okienku i kliknij przycisk -.
- Po zakończeniu kliknij przycisk OK.
- Określ parametry filtru w oknie dialogowym Utwórz nowy filtr logcat:
Jeśli wydaje Ci się, że nie widzisz żądanych komunikatów dziennika, spróbuj wybrać opcjęBez filtrów i wyszukać określone komunikaty dziennika.
Odczytaj komunikaty o zbieraniu śmieci
Czasami, gdy wystąpi zdarzenie zbierania śmieci, są one drukowane do pliku logcat.
Aby uzyskać więcej szczegółów na temat pamięci aplikacji, użyj narzędzia Memory Profiler.
Wiadomości dziennika Dalvik
W Dalviku (ale nie w ART), każde GC drukuje następujące informacje do logcat:
D/dalvikvm(PID): GC_Reason Amount_freed, Heap_stats, External_memory_stats, Pause_time
Przykład:
D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
GC Reason Co wywołało GC i jakiego rodzaju jest to zbieranie. Powody, które mogą się pojawićinclude:GC_CONCURRENT
Współbieżne GC, które zwalnia pamięć, gdy twoja sterta zaczyna się zapełniać.GC_FOR_MALLOC
GC zostało spowodowane, ponieważ twoja aplikacja próbowała przydzielić pamięć, gdy sterta była już pełna, więc system musiał zatrzymać twoją aplikację i odzyskać pamięć.GC_HPROF_DUMP_HEAP
GC, które występuje, gdy zażądasz utworzenia pliku HPROF w celu przeanalizowania sterty.GC_EXPLICIT
Jawne GC, takie jak wywołaniegc()
(którego powinieneś unikać i zamiast tego ufać, że GC zostanie uruchomione w razie potrzeby).GC_EXTERNAL_ALLOC
Dzieje się to tylko na poziomie API 10 i niższym (nowsze wersje alokują wszystko w stercie Dalvik). GC dla zewnętrznie przydzielonej pamięci (takiej jak dane pikseli przechowywane w pamięci wewnętrznej lub bufory bajtowe NIO). Amount freed Ilość pamięci odzyskanej z tego GC. Statystyki sterty Procent wolnego miejsca na stercie i (liczba żywych obiektów)/(całkowity rozmiar sterty). Statystyki pamięci zewnętrznej Zewnętrznie zaalokowana pamięć na poziomie API 10 i niższym (ilość zaalokowanej pamięci) / (limit, przy którym nastąpi pobranie). Czas pauzy Większe sterty będą miały większe czasy pauzy. Współbieżne czasy pauzy pokazują dwie pauzy: jedną na początku kolekcji i drugą pod koniec.
Podczas gromadzenia się tych komunikatów w dzienniku, zwróć uwagę na wzrost statystyk sterty (wartość3571K/9991K
w powyższym przykładzie). Jeśli ta wartość nadal rośnie, prawdopodobnie masz wyciek pamięci.
Wiadomości dziennikaART
W przeciwieństwie do Dalvika, ART nie rejestruje wiadomości dla GC, które nie zostały jawnie zażądane. GC są drukowane tylko wtedy, gdy są uważane za powolne. Dokładniej, jeśli pauza GC przekracza 5ms lub czas trwania GC przekracza 100ms. Jeśli aplikacja nie jest w stanie wyczuwalnej pauzy (np. gdy aplikacja jest w tle, gdzie użytkownik nie może zauważyć pauzy GC), to żadne z jej GC nie jest uważane za powolne. Wyraźne GC są zawsze rejestrowane.
ART zawiera następujące informacje w swoich komunikatach dziennika zbierania śmieci:
I/art: GC_Reason GC_Name Objects_freed(Size_freed) AllocSpace Objects, Large_objects_freed(Large_object_size_freed) Heap_stats LOS objects, Pause_time(s)
Przykład:
I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects, 21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms
GC Reason Co wywołało GC i jaki to rodzaj zbierania. Powody, które mogą się pojawić, obejmują:Concurrent
Współbieżne GC, które nie zawiesza wątków aplikacji. To GC działa w wątku tła i nie zapobiega alokacjom.Alloc
GC zostało zainicjowane, ponieważ Twoja aplikacja próbowała przydzielić pamięć, gdy sterta była już pełna. W tym przypadku, odśmiecanie nastąpiło w wątku alokującym.Explicit
Odśmiecanie zostało jawnie zażądane przez aplikację, na przykład przez wywołaniegc()
lubgc()
. Podobnie jak w Dalviku, w ART najlepszą praktyką jest ufanie GC i unikanie żądania jawnego GC, jeśli to możliwe.Jawne GC jest odradzane, ponieważ blokuje wątek alokujący i niepotrzebnie marnuje cykle procesora. Jawne GC może również spowodować jank (zacinanie się, juddering lub zatrzymanie aplikacji), jeśli spowoduje, że inne wątki zostaną uprzedzone.NativeAlloc
Zbiór był spowodowany przez natywną presję pamięci z natywnych alokacji, takich jak Bitmapy lub obiekty alokacji RenderScript.CollectorTransition
Zbiór był spowodowany przejściem sterty; jest to spowodowane zmianą strategii GC w czasie wykonywania (na przykład, gdy aplikacja zmienia się między stanami podatnymi na pauzę). Przejścia kolektora polegają na kopiowaniu wszystkich obiektów z przestrzeni wspartej wolną listą do przestrzeni wskaźnikowej bump (lub odwrotnie).
To występuje tylko na urządzeniach z niską pamięcią RAM przed Androidem 8.0, gdy aplikacja zmienia stan procesu ze stanu wyczuwalnej pauzy (np. gdy aplikacja jest na pierwszym planie, gdzie użytkownik może odebrać pauzę GC) na stan niewyczuwalnej pauzy (lub odwrotnie).
HomogeneousSpaceCompact
Homogeniczne zagęszczanie przestrzeni jest zagęszczaniem przestrzeni z wolnej listy do wolnej listy, które zwykle występuje, gdy aplikacja jest przenoszona do stanu procesu wyczuwalnej pauzy. Główne powody, dla których to robi, to zmniejszenie zużycia pamięci RAM i defragmentacja sterty.DisableMovingGc
To nie jest prawdziwy powód GC, ale uwaga, że kolekcja została zablokowana z powodu użyciaGetPrimitiveArrayCritical. podczas gdy współbieżne zagęszczanie sterty ma miejsce. Ogólnie rzecz biorąc, użycieGetPrimitiveArrayCritical jest zdecydowanie odradzane z powodu jego ograniczeń dotyczących przenoszenia kolektorów.HeapTrim
To nie jest powód GC, ale uwaga, że kolekcja została zablokowana do czasu zakończenia przycinania sterty. GC Name ART ma różne różne GC, które mogą zostać uruchomione.Concurrent mark sweep (CMS)
Kolektor całej sterty, który zwalnia wszystkie przestrzenie inne niż przestrzeń obrazu.Concurrent partial mark sweep
A mostly whole heap collector which collectes all spaces other than the image and zygote spaces.Concurrent sticky mark sweep
Generacyjny kolektor, który może uwolnić tylko obiekty zaalokowane od ostatniego GC. Ten garbagecollection jest uruchamiany częściej niż pełny lub częściowy mark sweep, ponieważ jest szybszy i ma mniejsze przerwy.Marksweep + semispace
Niewspółbieżny, kopiujący GC, używany do przechodzenia przez stertę, jak również do homogenicznej kompakcji przestrzeni (do defragmentacji sterty). Obiekty uwolnione Liczba obiektów, które zostały odzyskane z tego GC z przestrzeni bez dużych obiektów. Rozmiar uwolniony Liczba bajtów, które zostały odzyskane z tego GC z niedużej przestrzeni obiektowej. Duże obiekty uwolnione Liczba obiektów w przestrzeni dużych obiektów, które zostały odzyskane z tej kolekcji śmieci. Rozmiar dużych obiektów uwolniony Liczba bajtów w przestrzeni dużych obiektów, które zostały odzyskane z tej kolekcji śmieci. Statystyki sterty Procent wolnego i (liczba żywych obiektów)/(całkowity rozmiar sterty). Czasy pauzy Czasy pauzy są proporcjonalne do liczby odniesień do obiektów, które zostały zmodyfikowane w czasie działania GC. W chwili obecnej ART CMS GC ma tylko jedną pauzę, pod koniec GC, natomiast ruchome GC mają długą pauzę, która trwa przez większość czasu trwania GC.
Jeśli widzisz dużą ilość GC w logcat, poszukaj wzrostów w statystykach sterty (wartość25MB/38MB
w powyższym przykładzie). Jeśli ta wartość nadal rośnie i nie wydaje się zmniejszać, możesz mieć wyciek pamięci. Alternatywnie, jeśli widzisz GC, które mają powód „Alloc”, wtedy już działasz blisko pojemności sterty i możesz spodziewać się wyjątków OOM w najbliższej przyszłości.