La ventana de Logcat en Android Studio muestra los mensajes del sistema, como cuando se produce una recogida de basura, y los mensajes que ha añadido a su aplicación con la clase Log
. Muestra los mensajes en tiempo real y mantiene un historial para que pueda ver los mensajes más antiguos.
Para mostrar sólo la información de interés, puede crear filtros, modificar la cantidad de información que se muestra en los mensajes, establecer niveles de prioridad, mostrar los mensajes producidos por el código de la aplicación solamente, y buscar en el registro. Por defecto, logcats muestra sólo la salida del registro relacionada con la aplicación ejecutada más recientemente.
Cuando una aplicación lanza una excepción, logcat muestra un mensaje seguido del seguimiento de la pila asociado que contiene enlaces a la línea de código.
A partir de Android Studio 2.2, la ventana Ejecutar también muestra los mensajes de registro de la aplicación que se está ejecutando. Tenga en cuenta que puede configurar la salida de logcat, pero no la ventana de ejecución.
Ver los registros de su aplicación
Para mostrar los mensajes de registro de una aplicación:
- Construya y ejecute su aplicación en un dispositivo.
- Haga clic en Ver > Ventanas de herramientas > Logcat (o haga clic en Logcat en la barra de la ventana de herramientas).
La ventana Logcat muestra los mensajes de registro de la aplicación seleccionada, según lo seleccionado en las listas desplegables de la parte superior de la ventana, como se muestra en la figura 1.
Figura 1. Ventana de Logcat
Por defecto, logcat muestra sólo los mensajes de registro de su aplicación que se ejecuta en el dispositivo. Para cambiar este valor predeterminado, consulte cómo filtrar los mensajes de logcat.
La barra de herramientas de Logcat proporciona los siguientes botones:
- Borrar logcat : Haga clic para borrar el registro visible.
- Desplazarse hasta el final : Haga clic para saltar al final del registro y ver los últimos mensajes de registro. Si a continuación, haga clic en una línea en el registro, la vista se detiene el desplazamiento en ese punto.
- Subir el seguimiento de la pila y Bajar el seguimiento de la pila : Haga clic para navegar hacia arriba y hacia abajo por las trazas de pila en el registro, seleccionando los nombres de archivo posteriores (y viendo los números de línea correspondientes en el editor) que aparecen en las excepciones impresas. Este es el mismo comportamiento que cuando se hace clic en un nombre de archivo en el registro.
- Use soft wraps : Haga clic para habilitar la envoltura de líneas y evitar el desplazamiento horizontal (aunque cualquier cadena irrompible seguirá requiriendo el desplazamiento horizontal).
- Imprimir : Haga clic para imprimir los mensajes de logcat. Después de seleccionar sus preferencias de impresión en el diálogo que aparece, también puede elegir guardar en un PDF.
- Reiniciar : Haga clic para borrar el registro y reiniciar logcat. A diferencia del botón Borrar logcat, esto recupera y muestra los mensajes de registro anteriores, por lo que es más útil si Logcat deja de responder y no quiere perder sus mensajes de registro.
- Cabecera de Logcat : Haga clic para abrir el cuadro de diálogo Configurar encabezado de Logcat, donde puede personalizar la apariencia de cada mensaje de Logcat, como por ejemplo si desea mostrar la fecha y la hora.
- Captura de pantalla : Haga clic para capturar una pantalla.
- Grabación de pantalla : Haga clic para grabar un vídeo del dispositivo (durante un máximo de 3 minutos).
Escribir mensajes de registro
La clase Log
le permite crear mensajes de registro que aparecen en logcat. En general, debe utilizar los siguientes métodos de registro, enumerados en orden de mayor a menor prioridad (o, de menor a mayor verborrea):
-
Log.e(String, String)
(error) -
Log.w(String, String)
(advertencia) -
Log.i(String, String)
(información) -
Log.d(String, String)
(depuración) -
Log.v(String, String)
(verboso)
Vea la descripción de la clase Log
para una lista más completa de opciones.
Nunca debe compilar registros verbose en su aplicación, excepto durante el desarrollo. Los registros de depuración se compilan pero se eliminan en tiempo de ejecución, mientras que los registros de error, advertencia e información siempre se mantienen.
Para cada método de registro, el primer parámetro debe ser una etiqueta única y este segundo parámetro es el mensaje. La etiqueta de un mensaje de registro del sistema es una cadena corta que indica el componente del sistema del que procede el mensaje (por ejemplo, ActivityManager
). Su etiqueta puede ser cualquier cadena que le resulte útil, como el nombre de la clase actual.
Una buena convención es declarar una constante TAG
en su clase para utilizarla en el primer parámetro. Por ejemplo, puede crear un mensaje de registro de información de la siguiente manera:
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);
Nota: Los nombres de las etiquetas de más de 23 caracteres se truncan en la salida de logcat.
Formato del mensaje de logcat
Cada mensaje de registro de Android tiene una etiqueta y una prioridad asociada. La etiqueta de un mensaje de registro del sistema es una cadena corta que indica el componente del sistema del que procede el mensaje (por ejemplo, ActivityManager
). Una etiqueta definida por el usuario puede ser cualquier cadena que le resulte útil, como el nombre de la clase actual (la etiqueta recomendada). Se define en una llamada al método Log
, por ejemplo:
Kotlin
Log.d(tag, message)
Java
Log.d(tag, message);
La prioridad es uno de los siguientes valores:
- V: Verbose (prioridad más baja)
- D: Debug
- I: Info
- W: Warning
- E: Error
- A: Assert
El formato de los mensajes de registro es:
date time PID-TID/package priority/tag: message
Por ejemplo, el siguiente mensaje de registro tiene una prioridad de V
y una etiqueta de AuthZen
:
12-10 13:02:50.071 1901-4229/com.google.android.gms V/AuthZen: Handling delegate intent.
PID significa identificador de proceso y TID es identificador de hilo; pueden ser el mismo si sólo hay un hilo.
Establecer el nivel de registro
Puede controlar cuántos mensajes aparecen en logcat estableciendo el nivel de registro. Puede mostrar todos los mensajes, o sólo los mensajes que indican las condiciones más graves.
Recuerde que logcat sigue recogiendo todos los mensajes independientemente de la configuración del nivel de registro. La configuración sólo determina lo que logcat muestra.
En el menú Log level, seleccione uno de los siguientes valores:
- Verbose: Muestra todos los mensajes de registro (el valor predeterminado).
- Depuración: Mostrar los mensajes de registro de depuración que son útiles sólo durante el desarrollo, así como los niveles de mensajes inferiores en esta lista.
- Info: Mostrar los mensajes de registro esperados para el uso regular, así como los niveles de mensajes más bajos en esta lista.
- Warn: Mostrar posibles problemas que aún no son errores, así como los niveles de mensajes más bajos en esta lista.
- Error: Muestra las incidencias que han provocado errores, así como el nivel de mensaje inferior en esta lista.
- Assert: Mostrar cuestiones que el desarrollador espera que nunca debe suceder.
Buscar mensajes de logcat
Para buscar los mensajes que se muestran actualmente en logcat:
- Seleccione opcionalmente Regex si desea utilizar un patrón de búsqueda de expresión regular.
- Escriba una secuencia de caracteres en el campo de búsqueda .
La pantalla de salida de logcat cambia en consecuencia.
- Pulse Enter para almacenar la cadena de búsqueda en el menú durante esta sesión.
- Para repetir una búsqueda, elíjala en el menú de búsqueda. Seleccione o deseleccione Regex según sea necesario (la configuración no se recuerda).
Filtrar los mensajes de logcat
Una forma de reducir la salida del registro a un nivel manejable es restringirla mediante el uso de un filtro.
Nota: El filtro se aplica a su historial completo de logcat, no sólo a los mensajes que se muestran actualmente en logcat. Asegúrese de que sus otras opciones de visualización están configuradas adecuadamente para que pueda ver la salida del filtro que desea examinar.
Para definir y aplicar un filtro:
- En el menú del filtro, seleccione una opción de filtro:
- Mostrar sólo la aplicación seleccionada: Mostrar los mensajes producidos por el código de la aplicación solamente (el valor predeterminado). Logcat filtra los mensajes de registro utilizando el PID de la app activa.
- Sin filtros: No aplicar ningún filtro. Logcat muestra todos los mensajes de registro del dispositivo, independientemente del proceso seleccionado.
- Editar configuración de filtros: Crea o modifica un filtro personalizado. Por ejemplo, puede crear un filtro para ver los mensajes de registro de dos aplicaciones al mismo tiempo.
Después de definir los filtros, también puede seleccionarlos en el menú. Para quitarlos del menú, elimínelos.
- Si ha seleccionado Editar configuración de filtros, cree o modifique un filtro:
- Especifique los parámetros del filtro en el cuadro de diálogo Crear nuevo filtro Logcat:
- Nombre del filtro: Escriba el nombre de un filtro que desee definir, o selecciónelo en el panel izquierdo para modificar un filtro existente. El nombre puede contener caracteres en minúsculas, guiones bajos y dígitos solamente.
- Etiqueta de registro: Opcionalmente, especifica una etiqueta. Para más información, consulte Formato de mensajes de logcat.
- Mensaje de registro: Opcionalmente, especifica el texto del mensaje de registro. Para más información, consulte Formato de mensaje de logcat.
- Nombre del paquete: Opcionalmente, especifica un nombre de paquete. Para obtener más información, consulte Formato de mensaje de logcat.
- PID: especifica opcionalmente un ID de proceso. Para más información, consulte Formato de mensajes de logcat.
- Nivel de registro: Opcionalmente, seleccione un nivel de registro. Para obtener más información, consulte Establecer el nivel de registro.
- Regex: Seleccione esta opción para utilizar la sintaxis de expresión regular para ese parámetro.
- Haga clic en + para añadir la definición del filtro al panel izquierdo.
Para eliminar un filtro, selecciónelo en el panel izquierdo y haga clic en -.
- Cuando haya terminado, haga clic en Aceptar.
- Especifique los parámetros del filtro en el cuadro de diálogo Crear nuevo filtro Logcat:
Si cree que no ve los mensajes de registro que desea, pruebe a seleccionar Sin filtros y a buscar mensajes de registro concretos.
Leer mensajes de recolección de basura
A veces, cuando se produce un evento de recolección de basura, se imprimen en logcat.
Para obtener más detalles sobre la memoria de su aplicación, utilice el Perfil de Memoria.
Mensajes de registro de Dalvik
En Dalvik (pero no en ART), cada GC imprime la siguiente información a logcat:
D/dalvikvm(PID): GC_Reason Amount_freed, Heap_stats, External_memory_stats, Pause_time
Ejemplo:
D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
Razón de GC Lo que desencadenó la GC y qué tipo de colección es. Las razones que pueden aparecerincluyen:GC_CONCURRENT
Una GC concurrente que libera memoria mientras su heap comienza a llenarse.GC_FOR_MALLOC
Una GC causada porque tu aplicación intentó asignar memoria cuando tu heap ya estaba lleno, por lo que el sistema tuvo que detener tu aplicación y recuperar memoria.GC_HPROF_DUMP_HEAP
Una GC que se produce cuando se solicita la creación de un archivo HPROF para analizar su montón.GC_EXPLICIT
Una GC explícita, como cuando llamas agc()
(que deberías evitar llamar y en su lugar confiar en que la GC se ejecute cuando sea necesario).GC_EXTERNAL_ALLOC
Esto sólo ocurre en el nivel 10 de la API y en los niveles inferiores (las versiones más nuevas asignan todo en el Dalvikheap). Una GC para la memoria asignada externamente (como los datos de píxeles almacenados en la memoria interna o los búferes de bytes NIO). Cantidad liberada La cantidad de memoria recuperada de esta GC. Estadísticas del montón Porcentaje libre del montón y (número de objetos vivos)/(tamaño total del montón). Estadísticas de la memoria externa Memoria asignada externamente en el nivel 10 de la API e inferior (cantidad de memoria asignada) / (límite en el que se producirá la recolección). Tiempo de pausa Los montículos más grandes tendrán tiempos de pausa más grandes. Los tiempos de pausa concurrentes muestran dos pausas: una al principio de la colección y otra cerca del final.
Mientras se acumulan estos mensajes de registro, observe si aumentan las estadísticas del montón (el valor3571K/9991K
en el ejemplo anterior). Si este valor sigue aumentando, es posible que haya una fuga de memoria.
Mensajes de registro de ART
A diferencia de Dalvik, ART no registra los mensajes de las GC que no se han solicitado explícitamente. Las GCs sólo se imprimen cuando se consideran lentas. Más concretamente, si la pausa de la GC supera los 5ms o la duración de la GC supera los 100ms. Si la aplicación no está en un estado de pausa perceptible (como cuando la aplicación está en segundo plano, donde el usuario no puede percibir una pausa de GC), entonces ninguna de sus GCs se considera lenta. Las GC explícitas siempre se registran.
ART incluye la siguiente información en sus mensajes de registro de recolección de basura:
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)
Ejemplo:
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
Razón de la GC Qué desencadenó la GC y qué tipo de recolección es. Las razones que pueden aparecerincluyen:Concurrent
Una GC concurrente que no suspende los hilos de la aplicación. Esta GC se ejecuta en un hilo de fondoy no impide las asignaciones.Alloc
La GC se inició porque su aplicación intentó asignar memoria cuando su montón ya estaba lleno. En este caso, la recolección de basura ocurrió en el hilo de asignación.Explicit
La recolección de basura fue solicitada explícitamente por una aplicación, por ejemplo, llamando agc()
ogc()
. Al igual que Dalvik, en ART la mejor práctica es confiar en la GC y evitar solicitar GCs explícitas, si es posible. Las GCs explícitas también podrían causar jank (tartamudeo, juddering, o detención en la aplicación) si hacen que otros hilos se adelanten.NativeAlloc
La colección fue causada por la presión de la memoria nativa de las asignaciones nativas como Bitmaps o objetos de asignación de RenderScript.CollectorTransition
La colección fue causada por una transición de la pila; esto es causado por el cambio de la estrategia de GC en tiempo de ejecución (como cuando la aplicación cambia entre los estados de pausaperceptible). Las transiciones del colector consisten en copiar todos los objetos de un espacio respaldado por una lista libre a un espacio de puntero de bump (o viceversa).
Esto ocurre sólo en dispositivos con poca RAM anteriores a Android 8.0cuando una aplicación cambia de estado de proceso desde un estado perceptible de pausa (como cuando la aplicación está en primer plano, donde el usuario puede percibir una pausa de GC) a un estado no perceptible de pausa (o viceversa).
HomogeneousSpaceCompact
La compactación de espacio homogéneo es la compactación de espacio de lista libre a espacio de lista libre que normalmente ocurre cuando una aplicación se mueve a un estado de proceso imperceptible de pausa. Las principales razones para hacer esto son la reducción del uso de RAM y la desfragmentación de la pila.DisableMovingGc
Esta no es una razón real de GC, sino una nota de que la colección fue bloqueada debido al uso deGetPrimitiveArrayCritical. mientras que la compactación concurrente del heap está ocurriendo. En general, el uso deGetPrimitiveArrayCritical está fuertemente desaconsejado debido a sus restricciones en el movimiento de los recolectores.HeapTrim
Esto no es una razón de GC, sino una nota de que la colección fue bloqueada hasta que un recorte del montón terminó. GC Nombre ART tiene varios GCs diferentes que pueden ser ejecutados.Concurrent mark sweep (CMS)
Un recolector de montón completo que libera todos los espacios que no sean el espacio de la imagen.Concurrent partial mark sweep
Un recolector de montón completo que recoge todos los espacios que no sean el de imagen y el de cigoto.Concurrent sticky mark sweep
Un recolector generacional que sólo puede liberar objetos asignados desde la última GC. Este recolector de basura se ejecuta más a menudo que un barrido de marcas completo o parcial ya que es más rápido y tiene menos pausas.Marksweep + semispace
Una GC no concurrente, de copia, utilizada para las transiciones de la pila, así como para la compactación homogénea del espacio (para desfragmentar la pila). Objetos liberados El número de objetos que fueron recuperados de esta GC del espacio de objetos no grandes. Tamaño liberado El número de bytes que se recuperaron de esta GC del espacio de objetos no grandes. Objetos grandes liberados El número de objetos en el espacio de objetos grandes que fueron recuperados de esta colección de basura. Tamaño del objeto grande liberado El número de bytes en el espacio de objetos grandes que fueron recuperados de esta colección de basura. Estadísticas de la pila Porcentaje libre y (número de objetos vivos)/(tamaño total de la pila). Tiempos de pausa En general, los tiempos de pausa son proporcionales al número de referencias a objetos que se modificaron mientras se ejecutaba la GC. Actualmente, las GCs de ART CMS sólo tienen una pausa, cerca del final de la GC.Las GCs en movimiento tienen una pausa larga que dura la mayor parte de la duración de la GC.
Si está viendo una gran cantidad de GCs en logcat, busque incrementos en las estadísticas del montón (el valor25MB/38MB
en el ejemplo anterior). Si este valor sigue aumentando y no parece reducirse, podría tener una fuga de memoria. Alternativamente, si usted está viendo GC que son por la razón «Alloc», entonces usted ya está operando cerca de su capacidad de la pila y puede esperar excepcionesOOM en un futuro próximo.