La herramienta dumpsys
se ejecuta en dispositivos Android y proporciona información sobre los servicios del sistema. Puedes llamar a dumpsys
desde la línea de comandos usando Android Debug Bridge (ADB) a fin de obtener un resultado de diagnóstico para todos los servicios del sistema que se ejecutan en un dispositivo conectado.
Es posible que este diagnóstico sea más detallado de lo que deseas, por lo que deberás usar las opciones de línea de comandos que se describen a continuación para obtener uno que solo incluya los servicios del sistema que te interesan. En esta página, también se describe cómo usar dumpsys
para realizar tareas comunes, como la inspección de diagnósticos de entradas, memoria RAM, batería o red.
Sintaxis
La sintaxis general para usar el comando dumpsys
es la siguiente:
adb shell dumpsys [-t timeout] [--help | -l | --skip services | service [arguments] | -c | -h]
Para obtener un diagnóstico de todos los servicios del sistema de tu dispositivo conectado, solo ejecuta adb shell dumpsys
.
Sin embargo, obtendrás mucha más información de la que normalmente desearías. Para obtener resultados más fáciles de administrar, en el comando, especifica el servicio que deseas examinar. Por ejemplo, el siguiente comando proporciona datos del sistema para componentes de entrada, como pantallas táctiles o teclados integrados:
adb shell dumpsys input
Para obtener una lista completa de los servicios del sistema que puedes usar con dumpsys
, usa el siguiente comando:
adb shell dumpsys -l
Opciones de línea de comandos
En la siguiente tabla, se incluyen las opciones que tienes disponibles cuando usas dumpsys
.
Opción | Descripción |
---|---|
-t timeout
|
Especifica el tiempo de espera en segundos. Si no se especifica, el valor predeterminado es 10 segundos. |
--help
|
Imprime el texto de ayuda de la herramienta dumpsys . |
-l
|
Muestra una lista completa de los servicios del sistema que puedes usar con dumpsys . |
--skip services
|
Especifica los services que no deseas incluir en los resultados. |
service [arguments]
|
Especifica el service que deseas generar. Algunos servicios pueden permitirte pasar elementos arguments opcionales. Puedes obtener información sobre estos argumentos opcionales si pasas la opción -h con el servicio, como se muestra a continuación:
adb shell dumpsys procstats -h |
-c
|
Cuando especifiques ciertos servicios, agrega esta opción para obtener datos en un formato compatible con computadoras. |
-h
|
Para algunos servicios, agrega esta opción a fin de ver el texto de ayuda y obtener opciones adicionales. |
Cómo inspeccionar diagnósticos de entradas
Cuando especificas el servicio input
, como se muestra a continuación, se vuelca el estado de los dispositivos de entrada del sistema, como teclados y pantallas táctiles, y el procesamiento de eventos de entrada.
adb shell dumpsys input
El resultado varía según la versión de Android que se ejecuta en el dispositivo conectado. En las siguientes secciones, se describe el tipo de información que normalmente ves.
Estado del centro de eventos
A continuación, se muestra lo que puedes ver cuando inspeccionas el estado del centro de eventos del diagnóstico de entrada:
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 ...
Estado del lector de entrada
InputReader
se ocupa de decodificar los eventos de entrada del kernel. Su volcado del estado muestra información sobre cómo se configura cada dispositivo de entrada y los cambios de estado que se produjeron recientemente, como presionar o tocar teclas en la pantalla táctil.
En el siguiente ejemplo, se muestra el resultado para una pantalla táctil. Ten en cuenta la información sobre la resolución del dispositivo y los parámetros de calibración que se utilizaron.
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
Al final del volcado de estado del lector de entrada, hay información sobre los parámetros de configuración global, como el intervalo de toques.
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
Estado del despachador de entrada
InputDispatcher
se ocupa de enviar eventos de entrada a las aplicaciones.
Como puedes ver en los resultados de ejemplo a continuación, el volcado del estado incluye información sobre qué ventana se está tocando, el estado de la cola de entrada, si hay una ANR en curso, etc.
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
Aspectos que se deben verificar
La siguiente es una lista de aspectos que se deben tener en cuenta cuando inspeccionas los distintos resultados del servicio input
:
Estado del centro de eventos:
- Todos los dispositivos de entrada que esperas deben estar presentes.
- Cada dispositivo de entrada debe tener su correspondiente archivo de diseño de clave, archivo de mapa de caracteres clave y archivo de configuración del dispositivo de entrada. Si faltan archivos o estos tienen errores de sintaxis, no se cargarán.
- Cada dispositivo de entrada debe estar correctamente clasificado. Los bits del campo
Classes
corresponden a marcas enEventHub.h
, comoINPUT_DEVICE_CLASS_TOUCH_MT
. - El
BuiltInKeyboardId
es correcto. Si el dispositivo no tiene un teclado integrado, el ID debe ser-2
. De lo contrario, debería ser el ID del teclado integrado. - Si observas que
BuiltInKeyboardId
no es-2
, pero debería serlo, quiere decir que te falta un archivo de mapa de caracteres clave para un teclado de funciones especiales en alguna parte. Los teclados de funciones especiales deben tener archivos de mapa de caracteres clave que contengan solo la líneatype SPECIAL_FUNCTION
(es lo que mencionamos con respecto al archivotuna-gpio-keykad.kcm
).
Estado del lector de entrada:
- Todos los dispositivos de entrada esperados deben estar presentes.
- Cada dispositivo de entrada debe estar configurado correctamente. En particular, verifica que la pantalla táctil y los ejes del joystick sean correctos.
Estado del despachador de entrada:
- Todos los eventos de entrada se deben procesar según lo esperado.
- Después de tocar la pantalla táctil y ejecutar
dumpsys
al mismo tiempo, la líneaTouchStates
debe identificar correctamente la ventana que tocas.
Cómo probar el rendimiento de IU
Cuando se especifica el servicio gfxinfo
, se obtiene información de rendimiento relacionada con los fotogramas de animación que ocurren durante la fase de grabación.
El siguiente comando usa gfxinfo
para recopilar datos de rendimiento de la IU de un nombre de paquete especificado:
adb shell dumpsys gfxinfo package-name
También puedes incluir la opción framestats
a fin de proporcionar información de latencia aún más detallada de los fotogramas recientes. De esa forma, puedes buscar y depurar problemas con mayor precisión, como se muestra a continuación:
adb shell dumpsys gfxinfo package-name framestats
Si deseas obtener más información sobre el uso de gfxinfo
y framestats
para integrar mediciones del rendimiento de la IU en tus prácticas de prueba, consulta Cómo realizar pruebas de rendimiento de la IU.
Cómo inspeccionar diagnósticos de red
La especificación del servicio netstats
proporciona estadísticas de uso de la red recopiladas desde que se inició el dispositivo anterior. Para obtener información adicional, como información detallada del ID de usuario único (UID), incluye la opción detail
, como se muestra a continuación:
adb shell dumpsys netstats detail
El resultado varía según la versión de Android que se ejecuta en el dispositivo conectado. En las siguientes secciones, se describe el tipo de información que normalmente ves.
Interfaces activas e interfaces UID activas
El resultado de la siguiente muestra incluye las interfaces activas y las interfaces UID activas del dispositivo conectado. En la mayoría de los casos, la información de las interfaces activas y las interfaces UID activas es la misma.
Active interfaces: iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}] Active UID interfaces: iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}]
Estadísticas "Dev" y "Xt"
El siguiente es un resultado de muestra de la sección de estadísticas de desarrollo:
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
Estadísticas del UID
La siguiente es una muestra de estadísticas detalladas de cada 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
Para encontrar el UID de tu app, ejecuta este comando: adb shell dumpsys
package your-package-name
. Luego, busca la línea con la etiqueta userId
.
Por ejemplo, para encontrar el uso de red de la app "com.example.myapp", ejecuta el siguiente comando:
adb shell dumpsys package com.example.myapp | grep userId
El resultado debería ser similar al siguiente ejemplo:
userId=10007 gids=[3003, 1028, 1015]
Usa el volcado de ejemplo anterior, para buscar líneas que tengan uid=10007
. Existen dos de estas líneas: la primera indica una conexión a una red móvil y la segunda indica una conexión Wi-Fi. Debajo de cada línea, puedes ver la siguiente información para cada período de dos horas (que bucketDuration
especifica en milisegundos):
-
set=DEFAULT
indica el uso de red en primer plano, mientras queset=BACKGROUND
indica el uso en segundo plano.set=ALL
implica ambos. -
tag=0x0
indica la etiqueta del socket asociada con el tráfico. rxBytes
yrxPackets
representan los bytes recibidos y los paquetes recibidos en el intervalo correspondiente.txBytes
ytxPackets
representan los bytes enviados (transmitidos) y los paquetes enviados en el intervalo correspondiente.
Cómo inspeccionar el diagnóstico de la batería
Especificar el servicio batterystats
genera datos estadísticos interesantes sobre el uso de la batería de un dispositivo, organizados por ID de usuario único (UID). Si deseas aprender a usar dumpsys
para probar el funcionamiento de tu app con Descanso y App Standby, ve a Pruebas con los modos Descanso y App Standby.
El comando para batterystats
es el siguiente:
adb shell dumpsys batterystats options
Si quieres ver una lista de opciones adicionales disponibles para batterystats
, incluye la opción -h
. En el siguiente ejemplo, se muestran las estadísticas de uso de la batería para un paquete de apps específico desde la última vez que se cargó el dispositivo:
adb shell dumpsys batterystats --charged package-name
En general, el resultado incluye lo siguiente:
- Historial de eventos relacionados con la batería
- Estadísticas globales para el dispositivo
- Uso de energía aproximado por UID y componente de sistema
- Milisegundos móviles por app, por paquete
- Estadísticas globales de UID de sistema
- Estadísticas globales de UID de la app
Para obtener más información sobre cómo usar batterystats
y generar una vista HTML del resultado, lo cual facilita la comprensión y el diagnóstico de problemas relacionados con la batería, consulta Genera perfiles del uso de la batería con Batterystats y Battery Historian.
Cómo inspeccionar resultados compatibles con computadoras
Puedes generar resultados de batterystats
en formato CSV compatible con computadoras si usas el siguiente comando:
adb shell dumpsys batterystats --checkin
El siguiente es un ejemplo del resultado que deberías ver:
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 ...
Las observaciones sobre uso de batería pueden ser por UID o nivel de sistema. Los datos se seleccionan para su inclusión según su utilidad para analizar el rendimiento de la batería. Cada fila representa una observación con los siguientes elementos:
- Un marcador de posición en número entero
- El ID de usuario asociado con la observación
- El modo de agregación:
- "i" para información no vinculada con el estado cargado/no cargado
- "l" para --charged (uso desde la última carga).
- "u" para --unplugged (uso desde la última vez que se desconectó); dejó de estar disponible en Android 5.1.1
- Identificador de sección, que determina cómo interpretar los valores posteriores en la línea
En la siguiente tabla, se describen los diversos identificadores de sección que puedes ver:
Identificador de sección | Descripción | Campos restantes |
---|---|---|
vers |
Versión |
versión de registro, versión de parcela, versión de plataforma inicial, versión de plataforma final |
uid |
UID |
uid, nombre del paquete |
apk |
APK |
activaciones, APK, servicio, hora de inicio, inicios, lanzamientos |
pr |
Procesamiento |
proceso, usuario, sistema, primer plano, inicios |
sr |
Sensor |
número de sensor, tiempo, recuento |
vib |
Vibrador |
tiempo, recuento |
fg |
Primer plano |
tiempo, recuento |
st |
Hora del estado |
primer plano, activo, en ejecución |
wl |
Bloqueo de activación |
bloqueo de activación, tiempo completo, "f", recuento completo, tiempo parcial, "p", recuento parcial, tiempo de ventana, "w", recuento de ventanas |
sy |
Sincronización |
sincronización, tiempo, recuento |
jb |
Trabajo |
trabajo, tiempo, recuento |
kwl |
Bloqueo de activación de kernel |
bloqueo de activación de kernel, tiempo, recuento |
wr |
Motivo de activación |
motivo de activación, tiempo, recuento |
nt |
Red |
recepción de bytes móviles, transmisión de bytes móviles, recepción de bytes Wi-Fi, transmisión de bytes Wi-Fi, recepción de paquetes móviles, transmisión de paquetes móviles, recepción de paquetes Wi-Fi, transmisión de paquetes Wi-Fi, tiempo móvil activo, recuento móvil activo |
ua |
Actividad del usuario |
otros, botón, tocar |
bt |
Batería |
recuento de inicio, tiempo real de la batería, tiempo de actividad de la batería, tiempo real total, tiempo de actividad total, tiempo de inicio del reloj, pantalla de batería apagada en tiempo real, pantalla de batería apagada |
dc |
Descarga de la batería |
baja, alta, pantalla encendida, pantalla apagada |
lv |
Nivel de batería |
nivel inicial, nivel actual |
wfl |
Wi-Fi |
hora de activación de bloqueo de Wi-Fi completo, tiempo de búsqueda de Wi-Fi, tiempo de actividad de Wi-Fi, recuento de búsqueda de Wi-Fi, tiempo de inactividad de Wi-Fi, tiempo de recepción de Wi-Fi, tiempo de transmisión de Wi-Fi |
gwfl |
Wi-Fi global |
hora de activación de Wi-Fi, tiempo de actividad de Wi-Fi, tiempo de inactividad de Wi-Fi, tiempo de recepción de Wi-Fi, tiempo de transmisión de Wi-Fi, potencia de Wi-Fi (mAh) |
gble |
Bluetooth global |
tiempo de inactividad de Bluetooth, tiempo de recepción de Bluetooth, tiempo de transmisión de Bluetooth, potencia de Bluetooth (mAh) |
m |
Varios |
hora de activación de la pantalla, hora de activación del teléfono, tiempo de bloqueo de activación total, tiempo de bloqueo de activación parcial, tiempo de actividad de radio móvil, tiempo ajustado de actividad de radio móvil, tiempo interactivo, hora de habilitación de modo de ahorro de energía, cambios de conectividad, hora de habilitación de modo inactivo del dispositivo, recuento habilitado de modo inactivo del dispositivo, tiempo de inactividad del dispositivo, recuento de inactividad del dispositivo, recuento activo de radio móvil, tiempo desconocido activo de radio móvil |
gn |
Red global |
bytes totales de recepción móvil, bytes totales de transmisión móvil, bytes totales de recepción Wi-Fi, bytes totales de transmisión Wi-Fi, paquetes totales de recepción móvil, paquetes totales de transmisión móvil, paquetes totales de recepción Wi-Fi, paquetes totales de transmisión Wi-Fi |
br |
Brillo de pantalla |
oscuro, tenue, medio, claro, brillante |
sst |
Tiempo de búsqueda de señal |
tiempo de búsqueda de señal |
sgt |
Tiempo de intensidad de la señal |
ninguna, baja, moderada, buena, excelente |
sgc |
Recuento de intensidad de la señal |
ninguna, baja, moderada, buena, excelente |
dct |
Tiempo de conexión de datos |
ninguno, GPRS, EDGE, UMTS, CDMA, EVDO_0, EVDO_A, 1xRTT, HSDPA, HSUPA, HSPA, IDEN, EVDO_B, LTE, EHRPD, HSPAP, otros |
dcc |
Recuento de conexión de datos |
ninguno, GPRS, EDGE, UMTS, CDMA, EVDO_0, EVDO_A, 1xRTT, HSDPA, HSUPA, HSPA, IDEN, EVDO_B, LTE, EHRPD, HSPAP, otros |
wst |
Hora del estado de Wi-Fi |
apagado, búsqueda apagada, ninguna red, desconectado, en STA conectado, en P2P conectado, en STA P2P conectado, AP secundario |
wsc |
Recuento de estado de Wi-Fi |
apagado, búsqueda apagada, ninguna red, desconectado, en STA conectado, en P2P conectado, en STA P2P conectado, AP secundario |
wsst |
Hora del estado del solicitante de Wi-Fi |
inválido, desconectado, interfaz inhabilitada, inactivo, buscando, autenticando, asociando, asociado, protocolo de enlace de cuatro vías, protocolo de enlace grupal, completado, inactivo, no inicializado |
wssc |
Recuento de estado de solicitante de Wi-Fi |
inválido, desconectado, interfaz inhabilitada, inactivo, buscando, autenticando, asociando, asociado, protocolo de enlace de cuatro vías, protocolo de enlace grupal, completado, inactivo, no inicializado |
wsgt |
Tiempo de intensidad de la señal Wi-Fi |
ninguna, baja, moderada, buena, excelente |
wsgc |
Recuento de intensidad de la señal Wi-Fi |
ninguna, baja, moderada, buena, excelente |
bst |
Hora del estado de Bluetooth |
inactivo, bajo, medio, alto |
bsc |
Recuento del estado de Bluetooth |
inactivo, bajo, medio, alto |
pws |
Resumen de uso de energía |
capacidad de la batería, energía computada, energía agotada mínima, energía agotada máxima |
pwi |
Elemento de uso de energía |
etiqueta, mAh |
dsd |
Paso de descarga |
duración, nivel, pantalla, ahorro de energía |
csd |
Paso de carga |
duración, nivel, pantalla, ahorro de energía |
dtr |
Tiempo de descarga restante |
tiempo restante de la batería |
ctr |
Tiempo de carga restante |
tiempo de carga restante |
Nota: Antes de Android 6.0, el uso de energía para la radio Bluetooth, la radio móvil y Wi-Fi se rastreaba en la categoría de sección m (Varios). En Android 6.0 y versiones posteriores, el uso de energía de estos componentes se rastrea en la sección pwi (Elemento de uso de energía) con etiquetas individuales (wifi, blue, cell) para cada componente.
Cómo ver asignaciones de memoria
Tienes dos maneras diferentes de inspeccionar el uso de memoria de tu app: durante un período usando procstats
o en una instantánea en particular usando meminfo
.
En las secciones siguientes, se muestra cómo usar cualquiera de los métodos.
procstats
procstats
permite ver cómo se comporta tu app con el tiempo, por ejemplo, cuánto tiempo se ejecuta en segundo plano y cuánta memoria usa durante ese tiempo.
Te ayuda a encontrar rápidamente ineficiencias y comportamientos erróneos en la app, como pérdidas de memoria, que pueden afectar el rendimiento, en especial cuando se ejecuta en dispositivos con poca memoria. Su volcado de estado muestra estadísticas sobre el tiempo de ejecución de cada aplicación, el tamaño del conjunto proporcional (PSS), el tamaño del conjunto único (USS) y el tamaño del conjunto residente (RSS).
Para obtener estadísticas sobre el uso de memoria de la app durante las últimas tres horas, en formato natural, ejecuta el siguiente comando:
adb shell dumpsys procstats --hours 3
Como se puede ver en el siguiente ejemplo, el resultado muestra qué porcentaje de tiempo estuvo ejecutándose la aplicación, además del PSS, USS y RSS como minPSS-avgPSS-maxPSS/minUSS-avgUSS-maxUSS/minRSS-avgRSS-maxRSS
sobre el número de muestras.
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
Con el siguiente comando, puedes grabar en una instantánea la manera en que se divide la memoria de tu app entre diferentes tipos de asignación de memoria RAM:
adb shell dumpsys meminfo package_name|pid [-d]
El indicador "-d" ofrece más información relacionada con el uso de la memoria en Dalvik y ART.
Se muestra una lista de todas las asignaciones actuales de tu app, medidas en kilobytes.
Cuando inspecciones esta información, deberás estar familiarizado con los siguientes tipos de asignación:
- RAM privada (sincronizada y no sincronizada)
- Se trata de la memoria usada únicamente por tu proceso. Es el bloque de la memoria RAM que el sistema puede recuperar cuando se destruye el proceso de tu app. En general, la parte más importante de esto es la RAM no sincronizada privada, que es la más costosa, ya que solo su proceso la usa y su contenido solo existe en la RAM, por lo que no se puede paginar al almacenamiento (porque Android no usa el intercambio). Todas las asignaciones de montón nativas y de Dalvik que hagas estarán relacionadas con la memoria RAM privada no sincronizada. Las asignaciones nativas y de Dalvik que compartes con el proceso Zygote representan la memoria RAM no sincronizada compartida.
- Tamaño del conjunto proporcional (PSS)
- Se trata de una medición del uso de memoria RAM de tu app en la que se tienen en cuenta las páginas compartidas entre diferentes procesos. Cualquier página de memoria RAM que sea exclusiva de tu proceso contribuye al valor de PSS de manera directa, mientras que las páginas que se comparten con otros procesos contribuyen a este valor solo de forma proporcional a la cantidad compartida. Por ejemplo, una página que se comparta entre dos procesos sumará la mitad de su tamaño al PSS de cada proceso.
Una característica interesante de la medición del PSS es que puedes sumar el valor de PSS de todos los procesos para determinar la memoria real que estos usan. Esto significa que el valor de PSS es un buen indicador del espacio de memoria RAM real de un proceso y permite realizar comparaciones con respecto a la cantidad que usan otros procesos y la que se encuentra disponible en total.
A continuación, por ejemplo, se ofrece el resultado del proceso de visualización de mapas en un dispositivo Nexus 5. Hay mucha información aquí, pero los puntos de análisis claves se indican a continuación.
adb shell dumpsys meminfo com.google.android.apps.maps -d
Nota: La información que veas puede variar un poco respecto de lo que se muestra aquí, ya que algunos detalles del resultado difieren entre las versiones de la plataforma.
** 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
Aquí se muestra un dumpsys anterior sobre Dalvik de la app de 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
En general, concéntrate solamente en las columnas Pss Total
y Private Dirty
. En algunos casos, también hay datos interesantes en las columnas Private Clean
y Heap Alloc
. A continuación, se presenta más información sobre las diferentes asignaciones de memoria (filas) que debes observar:
Dalvik Heap
- RAM que usan las asignaciones de Dalvik en tu app. En
Pss Total
, se incluyen todas las asignaciones del proceso Zygote (ponderadas por el uso compartido de estas entre los procesos, como se describe en la definición de PSS que se mencionó antes). El número de la columnaPrivate Dirty
representa la memoria RAM real destinada únicamente al montón de tu app, compuesto por tus propias asignaciones y cualquier página de asignación Zygote que se haya modificado desde la bifurcación del proceso de tu app desde Zygote.Nota: En las versiones de plataforma más nuevas que tienen la sección
Dalvik Other
, los númerosPss Total
yPrivate Dirty
para el montón de Dalvik no incluyen la sobrecarga de Dalvik, como la compilación justo a tiempo (JIT) y el registro de GC, mientras que las versiones anteriores incluyen una lista combinada de esta información enDalvik
.Heap Alloc
es la cantidad de memoria de la cual hacen un seguimiento los asignadores de montón nativo y de Dalvik para tu app. Este valor es superior aPss Total
yPrivate Dirty
porque tu proceso se bifurcó desde Zygote e incluye asignaciones que tu proceso comparte con los demás. .so mmap
y.dex mmap
- Memoria RAM que se usa para código asignado
.so
(nativo) y.dex
(Dalvik o ART). El númeroPss Total
incluye el código de la plataforma que se comparte entre las apps.Private Clean
representa el código propio de tu app. Por lo general, el tamaño asignado real será mucho mayor: aquí, la memoria RAM incluye solo lo que actualmente debe estar en ella para código ejecutado por la app. Sin embargo, .so mmap presenta una memoria RAM privada no sincronizada de tamaño amplio. Esto se debe a correcciones en el código nativo que se realizaron cuando se cargó en su dirección final. .oat mmap
- Cantidad de memoria RAM usada por la imagen de código que se basa en las clases cargadas de manera previa y que comúnmente emplean varias apps. Esta imagen se comparte entre todas las apps y no se ve afectada por apps específicas.
.art mmap
- Cantidad de memoria RAM usada por la imagen del montón que se basa en las clases cargadas de manera previa y que comúnmente emplean varias apps. Esta imagen se comparte entre todas las apps y no se ve afectada por apps específicas. Si bien la imagen de ART contiene instancias de
Object
, no se tiene en cuenta para calcular el tamaño del montón. .Heap
(únicamente con la marca -d)- Cantidad de memoria del montón de tu app. Se excluyen objetos de los espacios de objetos grandes e imágenes, pero se incluyen el espacio de Zygote y el espacio fijo.
.LOS
(únicamente con la marca -d)- Cantidad de memoria RAM usada por el espacio de objetos grandes de ART. Se incluyen los objetos grandes de Zygote. Todos los objetos grandes son asignaciones primitivas de matrices superiores a 12 KB.
.GC
(únicamente con la marca -d)- El costo general de la recolección de elementos no utilizados. No es posible reducir esta sobrecarga.
.JITCache
(únicamente con la marca -d)- Cantidad de memoria usada por las cachés de código y datos de JIT. Por lo general, es un valor de cero debido a que todas las apps se compilarán en el momento de la instalación.
.Zygote
(únicamente con la marca -d)- Cantidad de memoria usada por el espacio de Zygote. Dicho espacio se crea durante el arranque del dispositivo y nunca se realizan asignaciones en él.
.NonMoving
(únicamente con la marca -d)- Cantidad de memoria RAM usada por el espacio fijo de ART. Dicho espacio contiene objetos no movibles especiales, como campos y métodos. Puedes reducir esta sección si usas menos campos y métodos en tu app.
.IndirectRef
(únicamente con la marca -d)- Cantidad de memoria RAM usada por las tablas de referencia indirecta de ART. Por lo general, esta cantidad es pequeña. Sin embargo, si es demasiado grande, se puede reducir disminuyendo la cantidad de referencias JNI globales y locales que se usan.
Unknown
- Cualquier página de memoria RAM que el sistema no pudo clasificar en uno de los demás elementos más específicos.
Actualmente, contiene asignaciones que, por lo general, son nativas y que la herramienta no puede identificar durante la recolección de estos datos debido a la selección aleatoria del diseño del espacio de direcciones (ASLR). Como sucede con el montón de Dalvik, el valor de
Pss Total
para Unknown tiene en cuenta las páginas compartidas con Zygote, yPrivate Dirty
es la memoria RAM desconocida dedicada únicamente a tu app. TOTAL
- Memoria RAM total de tamaño del conjunto proporcional (PSS) que usa tu proceso. Es la suma de todos los campos PSS que se hallan encima de este. Indica el espacio total de la memoria que ocupa tu proceso, que se puede comparar directamente con la de otros procesos y la memoria RAM disponible en total.
Private Dirty
yPrivate Clean
son las asignaciones totales dentro de tu proceso, que no se comparten con otros procesos. Juntas (en especialPrivate Dirty
), representan la cantidad de memoria RAM que se enviará nuevamente al sistema cuando se destruya tu proceso. La memoria RAM no sincronizada hace referencia a páginas que se modificaron y que, por lo tanto, deben permanecer dedicadas a la memoria RAM (porque no hay intercambio). La memoria RAM sincronizada representa páginas asignadas desde un archivo persistente (por ejemplo, el código que se ejecuta) y que, por lo tanto, se pueden paginar si no se usan durante un tiempo. ViewRootImpl
- Cantidad de vistas raíz activas en tu proceso. Cada vista raíz está asociada a una ventana, de modo que esto puede ayudarte a identificar fugas de memoria relacionadas con cuadros de diálogos u otras ventanas.
AppContexts
yActivities
- Cantidad de objetos
Context
yActivity
de la app actualmente activos en tu proceso. Esto puede ayudarte a identificar rápidamente objetosActivity
fugados que no estén sujetos a la recolección de elementos no usados debido a referencias estáticas sobre ellos, lo cual es común. A menudo, estos objetos tienen muchas otras asignaciones asociadas a ellos, lo cual los convierte en un buen elemento para realizar un seguimiento de fugas de memoria de gran envergadura.
Nota: Un objeto View
o Drawable
también hace referencia a la Activity
de la que proviene. Por ello, conservar un objeto View
o Drawable
también puede hacer que tu app presente una fuga de Activity
.