dumpsys
to narzędzie, które działa na urządzeniach z Androidem i zawiera informacje o usługach systemowych. Wywołaj dumpsys
z wiersza poleceń za pomocą Android Debug Bridge (ADB), aby uzyskać dane diagnostyczne dotyczące wszystkich usług systemowych działających na połączonym urządzeniu.
Wyniki są zwykle bardziej szczegółowe, niż potrzebujesz, dlatego na tej stronie użyj opcji wiersza poleceń, aby uzyskać wyniki tylko dla wybranych usług systemowych. Na tej stronie znajdziesz też opis sposobu korzystania z dumpsys
do wykonywania typowych zadań, takich jak sprawdzanie danych wejściowych, pamięci RAM, baterii czy diagnostyka sieci.
Składnia
Ogólna składnia funkcji dumpsys
:
adb shell dumpsys [-t timeout] [--help | -l | --skip services | service [arguments] | -c | -h]
Aby uzyskać dane diagnostyczne dotyczące wszystkich usług systemowych na połączonym urządzeniu, uruchom adb shell dumpsys
.
Jednak generuje to znacznie więcej informacji niż zwykle. Aby uzyskać bardziej przydatne dane wyjściowe, określ usługę, którą chcesz sprawdzić, podając ją w poleceniu. Na przykład poniższe polecenie udostępnia dane systemowe dotyczące komponentów wejściowych, takich jak ekrany dotykowe czy wbudowane klawiatury:
adb shell dumpsys input
Aby wyświetlić pełną listę usług systemowych, których możesz używać w przypadku dumpsys
, uruchom to polecenie:
adb shell dumpsys -l
Opcje wiersza poleceń
Tabela poniżej zawiera listę dostępnych opcji podczas korzystania z dumpsys
:
Option | Opis |
---|---|
-t timeout
|
Okres oczekiwania na odpowiedź (w sekundach). Jeśli nie określisz tu żadnej wartości, zostanie użyta wartość domyślna 10 sekund. |
--help
|
wydrukuj tekst pomocy dotyczący narzędzia dumpsys .
|
-l
|
Wyświetl pełną listę usług systemowych, których możesz używać w ramach dumpsys .
|
--skip services
|
Określ services, których nie chcesz uwzględniać w wyjściu. |
service [arguments]
|
Określ service, które chcesz wygenerować. Niektóre usługi mogą umożliwiać przekazywanie opcjonalnych arguments. Aby dowiedzieć się więcej o tych opcjonalnych argumentach, prześlij opcję -h z usługą:
adb shell dumpsys procstats -h |
-c
|
Gdy podajesz określone usługi, dołącz tę opcję, aby dane wyjściowe były w formacie zrozumiałym dla maszyn. |
-h
|
W przypadku niektórych usług kliknięcie tej opcji spowoduje wyświetlenie tekstu pomocy i dodatkowych opcji. |
Sprawdzanie danych diagnostycznych
Określanie usługi input
, jak pokazano w poniższym poleceniu, powoduje zrzut stanu urządzeń wejściowych systemu, takich jak klawiatury i ekrany dotykowe, oraz przetwarzanie zdarzeń wejściowych.
adb shell dumpsys input
Wyjście różni się w zależności od wersji Androida na połączonym urządzeniu. W sekcjach poniżej opisujemy typy informacji, które zwykle widzisz.
Stan Event Hub
Poniżej znajdziesz przykład tego, co możesz zobaczyć podczas sprawdzania stanu Event Hub w diagnostyce danych wejściowych:
INPUT MANAGER (dumpsys input) Event Hub State: BuiltInKeyboardId: -2 Devices: -1: Virtual Classes: 0x40000023 Path:Descriptor: a718a782d34bc767f4689c232d64d527998ea7fd Location: ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000 KeyLayoutFile: /system/usr/keylayout/Generic.kl KeyCharacterMapFile: /system/usr/keychars/Virtual.kcm ConfigurationFile: HaveKeyboardLayoutOverlay: false 1: msm8974-taiko-mtp-snd-card Headset Jack Classes: 0x00000080 Path: /dev/input/event5 Descriptor: c8e3782483b4837ead6602e20483c46ff801112c Location: ALSA ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000 KeyLayoutFile: KeyCharacterMapFile: ConfigurationFile: HaveKeyboardLayoutOverlay: false 2: msm8974-taiko-mtp-snd-card Button Jack Classes: 0x00000001 Path: /dev/input/event4 Descriptor: 96fe62b244c555351ec576b282232e787fb42bab Location: ALSA ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000 KeyLayoutFile: /system/usr/keylayout/msm8974-taiko-mtp-snd-card_Button_Jack.kl KeyCharacterMapFile: /system/usr/keychars/msm8974-taiko-mtp-snd-card_Button_Jack.kcm ConfigurationFile: HaveKeyboardLayoutOverlay: false 3: hs_detect Classes: 0x00000081 Path: /dev/input/event3 Descriptor: 485d69228e24f5e46da1598745890b214130dbc4 Location: ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0001, product=0x0001, version=0x0001 KeyLayoutFile: /system/usr/keylayout/hs_detect.kl KeyCharacterMapFile: /system/usr/keychars/hs_detect.kcm ConfigurationFile: HaveKeyboardLayoutOverlay: false ...
Stan czytnika
InputReader
odpowiada za dekodowanie zdarzeń wejściowych z jądra. Dump stanu zawiera informacje o konfiguracji każdego urządzenia wejściowego oraz o ostatnich zmianach stanu, takich jak naciśnięcia klawiszy lub dotknięcia ekranu dotykowego.
Ten przykład pokazuje dane wyjściowe na ekranie dotykowym. Zanotuj informacje o rozdzielczości urządzenia i użytych parametrach kalibracji.
Input Reader State ... Device 6: Melfas MMSxxx Touchscreen IsExternal: false Sources: 0x00001002 KeyboardType: 0 Motion Ranges: X: source=0x00001002, min=0.000, max=719.001, flat=0.000, fuzz=0.999 Y: source=0x00001002, min=0.000, max=1279.001, flat=0.000, fuzz=0.999 PRESSURE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000 SIZE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000 TOUCH_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000 TOUCH_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000 TOOL_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000 TOOL_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000 Touch Input Mapper: Parameters: GestureMode: spots DeviceType: touchScreen AssociatedDisplay: id=0, isExternal=false OrientationAware: true Raw Touch Axes: X: min=0, max=720, flat=0, fuzz=0, resolution=0 Y: min=0, max=1280, flat=0, fuzz=0, resolution=0 Pressure: min=0, max=255, flat=0, fuzz=0, resolution=0 TouchMajor: min=0, max=30, flat=0, fuzz=0, resolution=0 TouchMinor: unknown range ToolMajor: unknown range ToolMinor: unknown range Orientation: unknown range Distance: unknown range TiltX: unknown range TiltY: unknown range TrackingId: min=0, max=65535, flat=0, fuzz=0, resolution=0 Slot: min=0, max=9, flat=0, fuzz=0, resolution=0 Calibration: touch.size.calibration: diameter touch.size.scale: 10.000 touch.size.bias: 0.000 touch.size.isSummed: false touch.pressure.calibration: amplitude touch.pressure.scale: 0.005 touch.orientation.calibration: none touch.distance.calibration: none SurfaceWidth: 720px SurfaceHeight: 1280px SurfaceOrientation: 0 Translation and Scaling Factors: XScale: 0.999 YScale: 0.999 XPrecision: 1.001 YPrecision: 1.001 GeometricScale: 0.999 PressureScale: 0.005 SizeScale: 0.033 OrientationCenter: 0.000 OrientationScale: 0.000 DistanceScale: 0.000 HaveTilt: false TiltXCenter: 0.000 TiltXScale: 0.000 TiltYCenter: 0.000 TiltYScale: 0.000 Last Button State: 0x00000000 Last Raw Touch: pointerCount=0 Last Cooked Touch: pointerCount=0
Na końcu zrzutu stanu czytnika danych wejściowych znajdują się informacje o globalnych parametrach konfiguracji, takie jak interwał dotyku:
Configuration: ExcludedDeviceNames: [] VirtualKeyQuietTime: 0.0ms PointerVelocityControlParameters: scale=1.000, lowThreshold=500.000, highThreshold=3000.000, acceleration=3.000 WheelVelocityControlParameters: scale=1.000, lowThreshold=15.000, highThreshold=50.000, acceleration=4.000 PointerGesture: Enabled: true QuietInterval: 100.0ms DragMinSwitchSpeed: 50.0px/s TapInterval: 150.0ms TapDragInterval: 300.0ms TapSlop: 20.0px MultitouchSettleInterval: 100.0ms MultitouchMinDistance: 15.0px SwipeTransitionAngleCosine: 0.3 SwipeMaxWidthRatio: 0.2 MovementSpeedRatio: 0.8 ZoomSpeedRatio: 0.3
Stan modułu rozdzielnika danych
InputDispatcher
odpowiada za wysyłanie zdarzeń wprowadzania danych do aplikacji.
Jak widać na tym przykładowym wyjściu, zrzut stanu zawiera informacje o tym, które okno jest dotykane, o stanie kolejki danych wejściowych, o tym, czy trwa wyświetlanie błędu ANR, oraz inne informacje o zdarzeniach związanych z danymi wejściowymi:
Input Dispatcher State: DispatchEnabled: 1 DispatchFrozen: 0 FocusedApplication: <null> FocusedWindow: name='Window{3fb06dc3 u0 StatusBar}' TouchStates: <no displays touched> Windows: 0: name='Window{357bbbfe u0 SearchPanel}', displayId=0, paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01820100, type=0x000007e8, layer=211000, frame=[0,0][1080,1920], scale=1.000000, touchableRegion=[0,0][1080,1920], inputFeatures=0x00000000, ownerPid=22674, ownerUid=10020, dispatchingTimeout=5000.000ms 1: name='Window{3b14c0ca u0 NavigationBar}', displayId=0, paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01840068, type=0x000007e3, layer=201000, frame=[0,1776][1080,1920], scale=1.000000, touchableRegion=[0,1776][1080,1920], inputFeatures=0x00000000, ownerPid=22674, ownerUid=10020, dispatchingTimeout=5000.000ms 2: name='Window{2c7e849c u0 com.vito.lux}', displayId=0, paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x0089031a, type=0x000007d6, layer=191000, frame=[-495,-147][1575,1923], scale=1.000000, touchableRegion=[-495,-147][1575,1923], inputFeatures=0x00000000, ownerPid=4697, ownerUid=10084, dispatchingTimeout=5000.000ms ... MonitoringChannels: 0: 'WindowManager (server)' RecentQueue: length=10 MotionEvent(deviceId=4, source=0x00001002, action=2, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, displayId=0, pointers=[0: (335.0, 1465.0)]), policyFlags=0x62000000, age=217264.0ms MotionEvent(deviceId=4, source=0x00001002, action=1, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, displayId=0, pointers=[0: (335.0, 1465.0)]), policyFlags=0x62000000, age=217255.7ms MotionEvent(deviceId=4, source=0x00001002, action=0, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, displayId=0, pointers=[0: (330.0, 1283.0)]), policyFlags=0x62000000, age=216805.0ms ... PendingEvent: <none> InboundQueue: <empty> ReplacedKeys: <empty> Connections: 0: channelName='WindowManager (server)', windowName='monitor', status=NORMAL, monitor=true, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> 1: channelName='278c1d65 KeyguardScrim (server)', windowName='Window{278c1d65 u0 KeyguardScrim}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> 2: channelName='357bbbfe SearchPanel (server)', windowName='Window{357bbbfe u0 SearchPanel}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> ... AppSwitch: not pending 7: channelName='2280455f com.google.android.gm/com.google.android.gm.ConversationListActivityGmail (server)', windowName='Window{2280455f u0 com.google.android.gm/com.google.android.gm.ConversationListActivityGmail}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> 8: channelName='1a7be08a com.android.systemui/com.android.systemui.recents.RecentsActivity (server)', windowName='Window{1a7be08a u0 com.android.systemui/com.android.systemui.recents.RecentsActivity EXITING}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> 9: channelName='3b14c0ca NavigationBar (server)', windowName='Window{3b14c0ca u0 NavigationBar}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> ... Configuration: KeyRepeatDelay: 50.0ms KeyRepeatTimeout: 500.0ms
Sprawdzanie
Oto lista kwestii, które należy wziąć pod uwagę podczas sprawdzania danych wyjściowych usługi input
:
Stan centrum zdarzeń:
- Wszystkie oczekiwane urządzenia wejściowe są dostępne.
- Każde urządzenie wejściowe ma odpowiedni plik układu klawiszy, plik mapy znaków klawiszy oraz plik konfiguracji urządzenia wejściowego. Jeśli pliki są nieobecne lub zawierają błędy składni, nie są wczytywane.
- Każde urządzenie wejściowe jest prawidłowo sklasyfikowane. Bity w polu
Classes
odpowiadają flagom w zasadzieEventHub.h
, takim jakINPUT_DEVICE_CLASS_TOUCH_MT
. -
BuiltInKeyboardId
jest prawidłowe. Jeśli urządzenie nie ma wbudowanej klawiatury, identyfikator musi być-2
. W przeciwnym razie powinien to być identyfikator wbudowanej klawiatury. - Jeśli zauważysz, że
BuiltInKeyboardId
nie jest-2
, mimo że powinno, oznacza to, że brakuje Ci pliku z mapą znaków klawiszy do klawiatury specjalnej. Urządzenia z klawiaturą funkcyjną powinny mieć pliki mapy znaków klawiszy, które zawierają tylko wiersztype SPECIAL_FUNCTION
.
Stan czytnika danych:
- Wszystkie oczekiwane urządzenia wejściowe są dostępne.
- każde urządzenie wejściowe jest prawidłowo skonfigurowane; W szczególności sprawdź, czy ekran dotykowy i osi joysticka działają prawidłowo.
Stan modułu dystrybucji danych wejściowych:
- Wszystkie zdarzenia wejściowe są przetwarzane zgodnie z oczekiwaniami.
- Po dotknięciu ekranu dotykowego i jednoczesnym uruchomieniu
dumpsys
liniaTouchStates
poprawnie identyfikuje okno, które dotykasz.
Testowanie wydajności interfejsu
Określenie usługi gfxinfo
zapewnia dane wyjściowe z informacjami o wydajności dotyczącymi klatek animacji, które występują w fazie nagrywania.
Aby zebrać dane o skuteczności interfejsu użytkownika dla określonej nazwy pakietu, użyj polecenia gfxinfo
:
adb shell dumpsys gfxinfo package-name
Możesz też dołączyć opcję framestats
, aby przesłać jeszcze bardziej szczegółowe informacje o czasach wyświetlania ostatnich klatek, dzięki czemu łatwiej będzie Ci śledzić i rozwiązywać problemy:
adb shell dumpsys gfxinfo package-name framestats
Aby dowiedzieć się więcej o używaniu narzędzia gfxinfo
i framestats
do integrowania pomiarów wydajności interfejsu użytkownika z praktykami testowania, przeczytaj artykuł Tworzenie testu porównawczego makro.
Sprawdzanie diagnostyki sieci
Określanie usługi netstats
zapewnia statystyki dotyczące użytkowania sieci zebrane od czasu uruchomienia poprzedniego urządzenia. Aby wyprowadzać dodatkowe informacje, np. szczegółowe informacje o niepowtarzalnym identyfikatorze użytkownika (UID), użyj opcji detail
w ten sposób:
adb shell dumpsys netstats detail
Wyjście różni się w zależności od wersji Androida na połączonym urządzeniu. W sekcjach poniżej opisujemy typy informacji, które zwykle widzisz.
Aktywne interfejsy i aktywne interfejsy UID
Poniższy przykładowy wynik zawiera listę aktywnych interfejsów i interfejsów aktywnych UID na podłączonym urządzeniu. W większości przypadków informacje o aktywnych interfejsach i interfejsach z aktywnym identyfikatorem UID są takie same.
Active interfaces: iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}] Active UID interfaces: iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}]
Statystyki „Dev” i „Xt”
Poniżej znajdziesz przykładowy wynik w sekcji Statystyki dewelopera:
Dev stats: Pending bytes: 1798112 History since boot: ident=[{type=WIFI, subType=COMBINED, networkId="Guest", metered=false}] uid=-1 set=ALL tag=0x0 NetworkStatsHistory: bucketDuration=3600 st=1497891600 rb=1220280 rp=1573 tb=309870 tp=1271 op=0 st=1497895200 rb=29733 rp=145 tb=85354 tp=185 op=0 st=1497898800 rb=46784 rp=162 tb=42531 tp=192 op=0 st=1497902400 rb=27570 rp=111 tb=35990 tp=121 op=0 Xt stats: Pending bytes: 1771782 History since boot: ident=[{type=WIFI, subType=COMBINED, networkId="Guest", metered=false}] uid=-1 set=ALL tag=0x0 NetworkStatsHistory: bucketDuration=3600 st=1497891600 rb=1219598 rp=1557 tb=291628 tp=1255 op=0 st=1497895200 rb=29623 rp=142 tb=82699 tp=182 op=0 st=1497898800 rb=46684 rp=160 tb=39756 tp=191 op=0 st=1497902400 rb=27528 rp=110 tb=34266 tp=120 op=0
Statystyki UID
Poniżej znajdziesz przykład szczegółowych statystyk dotyczących każdego identyfikatora UID:
UID stats: Pending bytes: 744 Complete history: ident=[[type=MOBILE_SUPL, subType=COMBINED, subscriberId=311111...], [type=MOBILE, subType=COMBINED, subscriberId=311111...]] uid=10007 set=DEFAULT tag=0x0 NetworkStatsHistory: bucketDuration=7200000 bucketStart=1406167200000 activeTime=7200000 rxBytes=4666 rxPackets=7 txBytes=1597 txPackets=10 operations=0 ident=[[type=WIFI, subType=COMBINED, networkId="MySSID"]] uid=10007 set=DEFAULT tag=0x0 NetworkStatsHistory: bucketDuration=7200000 bucketStart=1406138400000 activeTime=7200000 rxBytes=17086802 rxPackets=15387 txBytes=1214969 txPackets=8036 operations=28 bucketStart=1406145600000 activeTime=7200000 rxBytes=2396424 rxPackets=2946 txBytes=464372 txPackets=2609 operations=70 bucketStart=1406152800000 activeTime=7200000 rxBytes=200907 rxPackets=606 txBytes=187418 txPackets=739 operations=0 bucketStart=1406160000000 activeTime=7200000 rxBytes=826017 rxPackets=1126 txBytes=267342 txPackets=1175 operations=35
Aby znaleźć identyfikator UID aplikacji, uruchom to polecenie: adb shell dumpsys
package your-package-name
. Następnie znajdź wiersz z oznaczeniem userId
.
Aby na przykład znaleźć wykorzystanie sieci przez aplikację „com.example.myapp”, uruchom to polecenie:
adb shell dumpsys package com.example.myapp | grep userId
Dane wyjściowe powinny wyglądać mniej więcej tak:
userId=10007 gids=[3003, 1028, 1015]
W poprzednim przykładowym zrzucie pliku szukaj wierszy z uid=10007
. Istnieją 2 takie linie – pierwsza wskazuje połączenie komórkowe, a druga – połączenie Wi-Fi. Pod każdym wierszem znajdziesz te informacje dotyczące każdego 2-godzinnego przedziału czasu, które bucketDuration
określa w milisekundach:
-
set=DEFAULT
oznacza użycie sieci na pierwszym planie, aset=BACKGROUND
– w tle.set=ALL
oznacza obie opcje. -
tag=0x0
wskazuje tag gniazda powiązany z ruchu. -
rxBytes
irxPackets
to odbierane bajty i odbierane pakiety w odpowiednim przedziale czasu. -
txBytes
itxPackets
to wysłane (przesłane) bajty i wysłane pakiety w odpowiednim przedziale czasu.
Sprawdzanie diagnostyki baterii
Określenie usługi batterystats
powoduje generowanie danych statystycznych dotyczących zużycia baterii na urządzeniu, uporządkowanych według unikalnego identyfikatora użytkownika (UID). Aby dowiedzieć się, jak używać dumpsys
do testowania aplikacji pod kątem Uśpienia i Czuwania aplikacji, przeczytaj artykuł Testowanie z użyciem Uśpienia i Czuwania aplikacji.
Polecenie batterystats
:
adb shell dumpsys batterystats options
Aby wyświetlić listę dodatkowych opcji dostępnych dla batterystats
, dodaj opcję -h
. Ten przykładowy kod zwraca statystyki wykorzystania baterii przez określony pakiet aplikacji od ostatniego naładowania urządzenia:
adb shell dumpsys batterystats --charged package-name
Dane wyjściowe zwykle obejmują:
- historia zdarzeń związanych z baterią.
- Statystyki globalne urządzenia
- Przybliżone zużycie energii na UID i komponent systemu
- Milisekundy na pakiet według aplikacji mobilnej
- Statystyki zbiorcze identyfikatora UID systemu
- Statystyki zbiorcze identyfikatora UID aplikacji
Aby dowiedzieć się więcej o używaniu narzędzia batterystats
i generowaniu wizualizacji HTML, która ułatwia zrozumienie i diagnozowanie problemów z baterią, przeczytaj artykuł Profilowanie wykorzystania baterii za pomocą Batterystats i Battery Historian.
Sprawdzanie danych wyjściowych przyjaznych dla maszyny
Aby wygenerować dane batterystats
w czytelnym dla komputera formacie CSV, użyj tego polecenia:
adb shell dumpsys batterystats --checkin
Oto przykład danych wyjściowych:
9,0,i,vers,11,116,K,L 9,0,i,uid,1000,android 9,0,i,uid,1000,com.android.providers.settings 9,0,i,uid,1000,com.android.inputdevices 9,0,i,uid,1000,com.android.server.telecom ... 9,0,i,dsd,1820451,97,s-,p- 9,0,i,dsd,3517481,98,s-,p- 9,0,l,bt,0,8548446,1000983,8566645,1019182,1418672206045,8541652,994188 9,0,l,gn,0,0,666932,495312,0,0,2104,1444 9,0,l,m,6794,0,8548446,8548446,0,0,0,666932,495312,0,697728,0,0,0,5797,0,0 ...
Dane o wykorzystaniu baterii mogą być podawane na podstawie identyfikatora UID lub na poziomie systemu. Dane są wybierane do uwzględnienia na podstawie ich przydatności do analizy wydajności baterii. Każdy wiersz reprezentuje obserwację i zawiera te elementy:
- Liczba całkowita zastępcza
- Identyfikator użytkownika powiązany z obserwacją
- Tryb agregacji:
i
dla informacji niezwiązanych ze stanem naładowany/nienaładowany.l
przez--charged
(wykorzystanie od ostatniego naładowania).u
dla--unplugged
(wykorzystanie od ostatniego odłączenia). Wycofane w Androidzie 5.1.1.
- Identyfikator sekcji, który określa sposób interpretacji kolejnych wartości w wierszu.
W tabeli poniżej opisano różne identyfikatory sekcji, które mogą się wyświetlać:
Identyfikator sekcji | Opis | Pozostałe pola |
---|---|---|
|
Wersja |
|
|
UID |
|
|
APK |
|
|
Proces |
|
|
Czujnik |
|
|
Wibrator |
|
|
Pierwszy plan |
|
|
Czas lokalny |
|
|
Blokada wybudzania |
|
|
Synchronizacja |
|
|
Zadanie |
|
|
Blokada uśpienia jądra |
|
|
Wakeup Reason |
|
|
Sieć |
|
|
Aktywność użytkownika |
|
|
Bateria |
|
|
Rozładowanie baterii |
|
|
Poziom baterii |
|
|
Wi-Fi |
|
|
Global Wi-Fi |
|
|
Global Bluetooth |
|
|
Inne |
|
|
Sieć globalna |
|
|
Jasność ekranu |
|
|
Czas skanowania sygnału |
|
|
Czas siły sygnału |
|
|
Liczba wartości siły sygnału |
|
|
Czas połączenia danych |
|
|
Liczba połączeń danych |
|
|
Czas stanu Wi-Fi |
|
|
Liczba stanów Wi-Fi |
|
|
Czas stanu żądającego klienta Wi-Fi |
|
|
Liczba stanów klienta Wi-Fi |
|
|
Czas siły sygnału Wi-Fi |
|
|
Liczba wartości siły sygnału Wi-Fi |
|
|
Czas stanu Bluetooth |
|
|
Liczba stanów Bluetooth |
|
|
Podsumowanie zużycia energii |
|
|
Element zużycia energii |
|
|
Krok wyładunku |
|
|
Etap obciążenia |
|
|
Pozostały czas rozładowania |
|
|
Pozostały czas ładowania |
|
Uwaga: przed Androidem 6.0 zużycie energii na potrzeby radia Bluetooth, radia komórkowego i Wi-Fi było śledzone w sekcji m
(Różne). W Androidzie 6.0 i nowszych zużycie energii tych komponentów jest śledzone w sekcji pwi
(Element zużycia energii) z osobnymi etykietami (wifi
, blue
, cell
) dla każdego komponentu.
Wyświetlanie alokacji pamięci
Korzystanie z pamięci przez aplikację możesz sprawdzić na 2 sposoby: w określonym przedziale czasu za pomocą funkcji procstats
lub w określonym momencie za pomocą funkcji meminfo
.
W sekcjach poniżej znajdziesz instrukcje korzystania z obu metod.
procstats
procstats
umożliwia sprawdzenie, jak aplikacja zachowuje się w czasie, w tym jak długo działa w tle i ile pamięci zużywa w tym czasie. Pomaga szybko wykrywać nieefektywność i nieprawidłowe działanie aplikacji, takie jak wycieki pamięci, które mogą wpływać na jej wydajność, zwłaszcza na urządzeniach z małą ilością pamięci. Dump stanu zawiera statystyki dotyczące czasu działania każdej aplikacji, proporcjonalnego rozmiaru zbioru (PSS), niepowtarzalnego rozmiaru zbioru (USS) i rezydentnego rozmiaru zbioru (RSS).
Aby uzyskać statystyki dotyczące wykorzystania pamięci przez aplikację w ciągu ostatnich 3 godzin w formacie czytelnym dla człowieka, uruchom to polecenie:
adb shell dumpsys procstats --hours 3
Jak widać w tym przykładzie, dane wyjściowe zawierają informacje o procentowym czasie działania aplikacji oraz wartości PSS, USS i RSS jako minPSS-avgPSS-maxPSS/minUSS-avgUSS-maxUSS/minRSS-avgRSS-maxRSS
w stosunku do liczby próbek.
AGGREGATED OVER LAST 3 HOURS: * com.android.systemui / u0a37 / v28: TOTAL: 100% (15MB-16MB-17MB/7.7MB-8.7MB-9.4MB/7.7MB-9.6MB-84MB over 178) Persistent: 100% (15MB-16MB-17MB/7.7MB-8.7MB-9.4MB/7.7MB-9.6MB-84MB over 178) * com.android.se / 1068 / v28: TOTAL: 100% (2.8MB-2.9MB-2.9MB/300KB-301KB-304KB/304KB-22MB-33MB over 3) Persistent: 100% (2.8MB-2.9MB-2.9MB/300KB-301KB-304KB/304KB-22MB-33MB over 3) * com.google.android.gms.persistent / u0a7 / v19056073: TOTAL: 100% (37MB-38MB-40MB/27MB-28MB-29MB/124MB-125MB-126MB over 2) Imp Fg: 100% (37MB-38MB-40MB/27MB-28MB-29MB/124MB-125MB-126MB over 2) ... * com.android.gallery3d / u0a62 / v40030: TOTAL: 0.01% Receiver: 0.01% (Cached): 54% (6.4MB-6.5MB-6.9MB/4.4MB-4.4MB-4.4MB/4.4MB-26MB-68MB over 6) * com.google.android.tvlauncher / u0a30 / v1010900130: TOTAL: 0.01% Receiver: 0.01% (Cached): 91% (5.8MB-13MB-14MB/3.5MB-10MB-12MB/12MB-33MB-78MB over 6) * com.android.vending:instant_app_installer / u0a16 / v81633968: TOTAL: 0.01% Receiver: 0.01% (Cached): 100% (14MB-15MB-16MB/3.8MB-4.2MB-5.1MB/3.8MB-30MB-95MB over 7) ... Run time Stats: SOff/Norm: +32m52s226ms SOn /Norm: +2h10m8s364ms Mod : +17s930ms TOTAL: +2h43m18s520ms Memory usage: Kernel : 265MB (38 samples) Native : 73MB (38 samples) Persist: 262MB (90 samples) Top : 190MB (325 samples) ImpFg : 204MB (569 samples) ImpBg : 754KB (345 samples) Service: 93MB (1912 samples) Receivr: 227KB (1169 samples) Home : 66MB (12 samples) LastAct: 30MB (255 samples) CchAct : 220MB (450 samples) CchCAct: 193MB (71 samples) CchEmty: 182MB (652 samples) Cached : 58MB (38 samples) Free : 60MB (38 samples) TOTAL : 1.9GB ServRst: 50KB (278 samples) Start time: 2015-04-08 13:44:18 Total elapsed time: +2h43m18s521ms (partial) libart.so
meminfo
Za pomocą tego polecenia możesz zarejestrować, jak pamięć aplikacji jest rozdzielana między różne typy przydziału pamięci RAM:
adb shell dumpsys meminfo [-d] package_name|pid
Flaga -d
wyświetla więcej informacji o wykorzystaniu pamięci przez Dalvik i ART.
Flaga -h
wyświetla wszystkie obsługiwane flagi.
Wyjście zawiera listę wszystkich bieżących alokacji aplikacji mierzonych w kilobajtach.
Podczas sprawdzania tych informacji musisz znać te typy alokacji:
- Pamięć RAM prywatna (czysta i brudna)
- To pamięć używana tylko przez Twój proces. To jest większość pamięci RAM, którą system może odzyskać, gdy proces aplikacji zostanie zniszczony. Najważniejszym elementem jest zazwyczaj prywatna pamięć podręczna, która jest najdroższa, ponieważ jest używana tylko przez Twój proces, a jej zawartość znajduje się tylko w pamięci podręcznej. Nie można jej przenieść na pamięć masową, ponieważ Android nie używa pamięci podręcznej. Wszystkie alokacje Dalvik i pamięci podręcznej są prywatne i brudne w RAM-ie. Dalvik i wewnętrzne alokacje udostępniane procesowi Zygote są udostępniane w ramach brudnej pamięci RAM.
- Proporcjonalna wielkość zbioru (PSS)
- To pomiar wykorzystania pamięci RAM przez aplikację, który uwzględnia udostępnianie stron w różnych procesach. Wszystkie strony pamięci RAM, które są unikalne dla Twojego procesu, bezpośrednio wpływają na wartość PSS, natomiast strony udostępniane innym procesom wpływają na wartość PSS tylko proporcjonalnie do ilości udostępnień. Na przykład strona udostępniana przez 2 procesy przyczynia się do połowy swojego rozmiaru do PSS każdego z nich.
Charakterystyczną cechą pomiaru PSS jest to, że można go zsumować dla wszystkich procesów, aby określić rzeczywistą pamięć używaną przez wszystkie procesy. Oznacza to, że PSS to dobry wskaźnik rzeczywistego obciążenia pamięci RAM przez proces oraz porównania z wykorzystaniem pamięci RAM przez inne procesy i łączną dostępną pamięcią RAM.
Oto przykład danych wyjściowych procesu Map na urządzeniu Nexus 5:
adb shell dumpsys meminfo -d com.google.android.apps.maps
Uwaga: informacje, które widzisz, mogą się nieznacznie różnić od tych podanych tutaj, ponieważ niektóre szczegóły danych wyjściowych różnią się w zależności od wersji platformy.
** MEMINFO in pid 18227 [com.google.android.apps.maps] ** Pss Private Private Swapped Heap Heap Heap Total Dirty Clean Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ ------ Native Heap 10468 10408 0 0 20480 14462 6017 Dalvik Heap 34340 33816 0 0 62436 53883 8553 Dalvik Other 972 972 0 0 Stack 1144 1144 0 0 Gfx dev 35300 35300 0 0 Other dev 5 0 4 0 .so mmap 1943 504 188 0 .apk mmap 598 0 136 0 .ttf mmap 134 0 68 0 .dex mmap 3908 0 3904 0 .oat mmap 1344 0 56 0 .art mmap 2037 1784 28 0 Other mmap 30 4 0 0 EGL mtrack 73072 73072 0 0 GL mtrack 51044 51044 0 0 Unknown 185 184 0 0 TOTAL 216524 208232 4384 0 82916 68345 14570 Dalvik Details .Heap 6568 6568 0 0 .LOS 24771 24404 0 0 .GC 500 500 0 0 .JITCache 428 428 0 0 .Zygote 1093 936 0 0 .NonMoving 1908 1908 0 0 .IndirectRef 44 44 0 0 Objects Views: 90 ViewRootImpl: 1 AppContexts: 4 Activities: 1 Assets: 2 AssetManagers: 2 Local Binders: 21 Proxy Binders: 28 Parcel memory: 18 Parcel count: 74 Death Recipients: 2 OpenSSL Sockets: 2
Oto starszy dumpsys
w Dalviku aplikacji Gmail:
** MEMINFO in pid 9953 [com.google.android.gm] ** Pss Pss Shared Private Shared Private Heap Heap Heap Total Clean Dirty Dirty Clean Clean Size Alloc Free ------ ------ ------ ------ ------ ------ ------ ------ ------ Native Heap 0 0 0 0 0 0 7800 7637(6) 126 Dalvik Heap 5110(3) 0 4136 4988(3) 0 0 9168 8958(6) 210 Dalvik Other 2850 0 2684 2772 0 0 Stack 36 0 8 36 0 0 Cursor 136 0 0 136 0 0 Ashmem 12 0 28 0 0 0 Other dev 380 0 24 376 0 4 .so mmap 5443(5) 1996 2584 2664(5) 5788 1996(5) .apk mmap 235 32 0 0 1252 32 .ttf mmap 36 12 0 0 88 12 .dex mmap 3019(5) 2148 0 0 8936 2148(5) Other mmap 107 0 8 8 324 68 Unknown 6994(4) 0 252 6992(4) 0 0 TOTAL 24358(1) 4188 9724 17972(2)16388 4260(2)16968 16595 336 Objects Views: 426 ViewRootImpl: 3(8) AppContexts: 6(7) Activities: 2(7) Assets: 2 AssetManagers: 2 Local Binders: 64 Proxy Binders: 34 Death Recipients: 0 OpenSSL Sockets: 1 SQL MEMORY_USED: 1739 PAGECACHE_OVERFLOW: 1164 MALLOC_SIZE: 62
Zasadniczo należy zwracać uwagę tylko na kolumny Pss Total
i Private Dirty
.
W niektórych przypadkach kolumny Private Clean
i Heap Alloc
mogą też zawierać interesujące dane.
Poniżej znajdziesz więcej informacji o różnych alokacjach pamięci, które należy wziąć pod uwagę:
Dalvik Heap
- Pamięć RAM używana przez alokacje Dalvik w aplikacji. Wartość
Pss Total
obejmuje wszystkie alokacje Zygote, ważone przez ich współdzielenie w procesach, zgodnie z definicją PSS. LiczbaPrivate Dirty
to rzeczywista pamięć RAM przydzielona tylko stosowi aplikacji, składająca się z Twoich własnych alokacji i dowolnych stron alokacji Zygote, które zostały zmodyfikowane od czasu odgałęzienia procesu aplikacji z Zygote.Uwaga: w nowszych wersjach platformy, które zawierają sekcję
Dalvik Other
, wartościPss Total
iPrivate Dirty
dla stosu Dalvik nie obejmują obciążenia Dalvik, takiego jak kompilacja w czasie wykonywania (JIT) i prowadzenie księgi GC, podczas gdy starsze wersje podają te wartości w sekcjiDalvik
.Heap Alloc
to ilość pamięci, którą Dalvik i domyślni alokatorzy stosu śledzą w przypadku Twojej aplikacji. Ta wartość jest większa niżPss Total
iPrivate Dirty
, ponieważ Twój proces został utworzony przez zgałęzienie z Zygote i zawiera alokacje, które Twój proces udostępnia wszystkim innym. .so mmap
i.dex mmap
- Pamięć RAM używana do mapowanego kodu
.so
(natywnego) i.dex
(Dalvik lub ART). LiczbaPss Total
obejmuje kod platformy używany w różnych aplikacjach.Private Clean
to kod Twojej aplikacji. Zazwyczaj rzeczywisty rozmiar mapowania jest większy. Tutaj RAM to tylko to, co obecnie musi być w RAM-ie dla kodu uruchomionego przez aplikację. Jednak.so mmap
ma duży prywatny stan nieaktualny, który jest spowodowany poprawkami w kodzie natywnym podczas wczytywania go do ostatecznego adresu. .oat mmap
- To ilość pamięci RAM używanej przez obraz kodu. Jest ona oparta na wstępnie załadowanych klasach, które są często używane przez wiele aplikacji. To zdjęcie jest wspólne dla wszystkich aplikacji i nie zależy od konkretnych aplikacji.
.art mmap
- To ilość pamięci RAM używanej przez obraz stosu. Jest ona oparta na wstępnie załadowanych klasach, które są często używane przez wiele aplikacji. Ten obraz jest udostępniany wszystkim aplikacjom i nie jest zależny od konkretnych aplikacji. Mimo że obraz ART zawiera
Object
instancji, nie wlicza się on do rozmiaru stosu. .Heap
(tylko z flagą-d
)- To ilość pamięci stosu aplikacji. Nie obejmuje obiektów w pamięci obrazu i pamięci dużych obiektów, ale obejmuje przestrzeń zygote i nieruchomą.
.LOS
(tylko z flagą-d
)- To ilość pamięci RAM używanej przez duży obszar obiektów w ART. Obejmuje to duże obiekty Zygote. Duże obiekty to wszystkie przydzielenia tablic prymitywnych o większym rozmiarze niż 12 KB.
.GC
(tylko z flagą-d
)- To koszty ogólne związane z czyszczeniem pamięci. Nie ma możliwości zmniejszenia tego obciążenia.
.JITCache
(tylko z flagą-d
)- To ilość pamięci używanej przez dane JIT i pamięć podręczną kodu. Zwykle jest to 0, ponieważ wszystkie aplikacje są kompilowane w momencie instalacji.
.Zygote
(tylko z flagą-d
)- To ilość pamięci używanej przez przestrzeń Zygote. Przestrzeń Zygote jest tworzona podczas uruchamiania urządzenia i nigdy nie jest przydzielana.
.NonMoving
(tylko z flagą-d
)- To ilość pamięci RAM używanej przez nieruchomą przestrzeń ART. Przestrzeń nieruchoma zawiera specjalne obiekty, których nie można przenosić, takie jak pola i metody. Możesz zmniejszyć rozmiar tej sekcji, używając w aplikacji mniejszej liczby pól i metod.
.IndirectRef
(tylko z flagą-d
)- To ilość pamięci RAM używanej przez tabele odwołań pośrednich ART. Zwykle jest ona niewielka, ale jeśli jest zbyt wysoka, możesz ją zmniejszyć, zmniejszając liczbę lokalnych i globalnych odwołań do JNI.
Unknown
- Wszystkie strony RAM, których system nie mógł zaklasyfikować jako żadnego z innych, bardziej szczegółowych elementów. Obecnie zawiera ona głównie natywne alokacje, których narzędzie nie może zidentyfikować podczas zbierania tych danych z powodu losowego rozmieszczania adresów (ASLR). Podobnie jak w przypadku stosu Dalvik, wartość
Pss Total
wUnknown
uwzględnia udostępnianie z Zygote, a wartośćPrivate Dirty
to nieznany obszar pamięci RAM przeznaczony tylko dla Twojej aplikacji. TOTAL
- Łączna pamięć RAM proporcjonalnego zbioru (PSS) używana przez proces. Jest to suma wszystkich pól PSS powyżej. Wskazuje on ogólną ilość pamięci zajmowanej przez proces, którą można bezpośrednio porównać z innymi procesami i całkowitą dostępną pamięcią RAM.
Private Dirty
iPrivate Clean
to łączne alokacje w ramach procesu, które nie są udostępniane innym procesom. Gdy proces zostanie zniszczony, cała pamięć RAM z tych alokacji zostanie zwolniona z powrotem do systemu.Private Clean
może też zostać wyzwolony przed zniszczeniem procesu, alePrivate Dirty
jest uwalniany dopiero po zniszczenie procesu.Zanieczyszczona pamięć RAM to strony, które zostały zmodyfikowane, dlatego muszą pozostać w pamięci RAM, ponieważ nie ma możliwości przeniesienia ich na dysk. Czysta pamięć RAM to strony zamapowane z pliku trwałego, np. kodu, który jest wykonywany, i które mogą zostać wykasowane z pamięci, jeśli przez jakiś czas nie są używane.
ViewRootImpl
- Liczba widoków okna głównego, które są aktywne w procesie. Każdy widok główny jest powiązany z oknem, więc może to pomóc w identyfikacji wycieków pamięci związanych z dialogami lub innymi oknami.
AppContexts
iActivities
- Liczba obiektów aplikacji
Context
iActivity
, które są obecnie aktywne w Twoim procesie. Dzięki temu możesz szybko identyfikować przeciekiActivity
obiektów, których nie można usunąć za pomocą funkcji garbage collection z powodu odwołań statycznych, co jest częstym problemem. Takie obiekty często mają wiele innych przypisanych alokacji, co sprawia, że są one dobrym sposobem na śledzenie dużych wycieków pamięci.