Skip to content

Most visited

Recently visited

navigation

Ver asignaciones de montones de Java y de memoria con Memory Profiler

Memory Profiler es un componente de Android Profiler que te ayuda a identificar fugas y migraciones de memoria que puedan generar interrupciones, congelamiento e incluso bloqueo en la app. En él se muestra un gráfico en tiempo real con el uso de memoria de tu app, y te permite capturar un volcado de montón, forzar la recolección de elementos no usados y realizar el seguimiento de asignaciones de memoria.

Para abrir Memory Profiler, sigue estos pasos:

  1. Haz clic en View > Tool Windows > Android Profiler (también puedes hacer clic en Android Profiler en la barra de herramientas).
  2. Selecciona el dispositivo y el proceso de la app del cual desees generar un perfil en la barra de herramientas del generador de perfiles de Android. Si conectaste un dispositivo mediante USB, pero no lo ves en la lista, asegúrate de haber habilitado la depuración USB.
  3. Haz clic en cualquier parte de la línea de tiempo MEMORY para abrir Memory Profiler.

Como alternativa, puedes inspeccionar la memoria de tu app desde la línea de comandos con dumpsys y también ver eventos de recolección de elementos no usados en logcat.

Por qué debes generar perfiles para la memoria de tu app

Android proporciona un entorno de memoria administrada. Cuando determina que tu app ya no usa algunos objetos, el recolector de elementos no usados libera la memoria no usada para devolverla al montón. La forma en la que Android busca memoria sin usar se somete a optimizaciones constantes. Sin embargo, en algún punto en todas las versiones de Android, el sistema debe pausar brevemente tu código. La mayoría de las veces, las pausas son imperceptibles. Sin embargo, si tu app asigna memoria a una velocidad que supera la que el sistema es capaz de alcanzar para recolectarla, tu app podría experimentar una demora mientras el recolector libera suficiente memoria para satisfacer tus asignaciones. La demora podría hacer que tu app omitiera fotogramas y causara una lentitud visible.

Aun cuando tu app no muestre lentitud, si tiene fugas de memoria puede retenerla incluso mientras se encuentre en segundo plano. Este comportamiento puede desacelerar el rendimiento del resto de la memoria del sistema al forzar eventos innecesarios de recolección de elementos no usados. Eventualmente, el sistema se ve forzado a finalizar el proceso de tu app para recuperar la memoria. Luego, cuando el usuario regresa a tu app, esta debe reiniciarse por completo.

A fin de evitar estos problemas, debes usar Memory Profiler para lo siguiente:

Para obtener más información sobre prácticas de programación que pueden reducir el uso de memoria de tu app, consulta Administra la memoria de tu app.

Información general sobre Memory Profiler

Cuando abras Memory Profiler por primera vez, verás una línea de tiempo detallada del uso de memoria de tu app y herramientas de acceso para forzar la recolección de elementos no usados, capturar un volcado de montón y registrar asignaciones de memoria.

Figura 1: Memory Profiler.

Como se indica en la figura 1, en la vista predeterminada para Memory Profiler se incluye lo siguiente:

  1. Un botón para forzar un evento de recolección de elementos no usados.
  2. Un botón para capturar un vaciado de montón.
  3. Un botón para registrar asignaciones de memoria. Este botón aparece únicamente cuando se conecta a un dispositivo con Android 7.1 o anterior.
  4. Botones para acercar y alejar la vista de la línea de tiempo.
  5. Un botón para ir directo a los datos de memoria en tiempo real.
  6. La línea de tiempo de eventos, en la que se muestran los estados de actividad, eventos de entrada del usuario y eventos de rotación de pantalla.
  7. La línea de tiempo de uso de memoria, que incluye lo siguiente:
    • Un gráfico apilado del volumen de memoria que se usa en cada categoría de memoria, como se indica con el eje Y a la izquierda, y la clave de color, en la parte superior.
    • Una línea punteada indica la cantidad de objetos asignados, como se indica con el eje Y a la derecha.
    • Un ícono para cada evento de recolección de elementos no usados.

Sin embargo, si usas un dispositivo con Android 7.1 o versiones anteriores, no se verá toda la información de generación de perfiles de manera predeterminada. Si ves el mensaje con la leyenda “Advanced profiling is unavailable for the selected process” (la generación de perfiles avanzada no se encuentra disponible para el proceso seleccionado), debes habilitar la generación de perfiles avanzada para ver lo siguiente:

En Android 8.0 y versiones posteriores, la generación de perfiles avanzada siempre se encuentra habilitada para apps depurables.

Cómo se recuenta la memoria

Los números que ves en la parte superior de Memory Profiler (figura 2) se basan en todas las páginas privadas de memoria que tu app confirma, según el sistema de Android. Este recuento no incluye páginas compartidas con el sistema ni otras apps.

Figura 2: Leyenda del recuento de memoria en la parte superior de Memory Profiler.

Las categorías en el recuento de memoria son las siguientes:

Cuando se compara con los recuentos de memoria de la herramienta anterior, Android Monitor, el nuevo Memory Profiler registra tu memoria de manera diferente, por lo cual podría parecer que tu uso de memoria ahora fuera más elevado. Memory Profiler supervisa algunas categorías adicionales que aumentan el total, pero si solo te importa la memoria del montón de Java el número de “Java” debería ser similar al valor en la herramienta anterior.

Además, aunque el número de Java probablemente no sea exactamente igual al que viste en Android Monitor, el número nuevo contempla todas las páginas de memoria física asignadas al montón de Java de tu app desde que se bifurcó desde Zygote. Por lo tanto, esto proporciona una representación precisa del volumen de memoria física que realmente usa tu app.

Nota: Actualmente, Memory Profiler también muestra algunos casos falsos positivos de uso de memoria nativa en tu app que en realidad pertenece a las herramientas de generación de perfiles. Se agregan hasta 10 MB de memoria por cada 100 mil objetos aproximadamente. En una versión futura de las herramientas, estos números se excluirán de tus datos.

Ver asignaciones de memoria

Las asignaciones de memoria te muestran la manera en que se asignó cada objeto en tu memoria. Específicamente, Memory Profiler puede mostrarte lo siguiente sobre la asignación de objetos:

Si tu dispositivo ejecuta Android 8.0 o versiones posteriores, puedes ver tus asignaciones de objetos en cualquier momento de la siguiente manera: Simplemente haz clic sobre la línea de tiempo, mantén presionado el botón y arrástrala para seleccionar la región en la que deseas ver las asignaciones (como se muestra en el video 1). No hay necesidad de comenzar una sesión de registro, ya que Android 8.0 y las versiones posteriores incluyen una herramienta de generación de perfiles en el dispositivo que constantemente realiza un seguimiento de las asignaciones de tu app.

Video 1: Con Android 8.0 y versiones posteriores, selecciona un área de la línea de tiempo existente para ver las asignaciones de objetos.

Si tu dispositivo tiene Android 7.1 o una versión anterior, haz clic en Record memory allocations en la barra de herramientas de Memory Profiler. Durante el registro, Android Monitor realiza el seguimiento de todas las asignaciones que ocurren en tu app. Cuando termines, haz clic en Stop recording (el mismo botón, mira el video 2) para ver las asignaciones.

Video 2: Con Android 7.1 y versiones anteriores, debes registrar las asignaciones de memoria de manera explícita.

Cuando selecciones una región de la línea de tiempo (o cuando termines una sesión de registro con un dispositivo con Android 7.1 o una versión anterior), la lista de objetos asignados aparece debajo de la línea de tiempo, y los objetos se muestran agrupados por nombre de clase y ordenados por recuento de montón.

Nota: En Android 7.1 y versiones anteriores, puedes registrar 65535 asignaciones como máximo. Si tu sesión de registro excede este límite, únicamente las 65535 asignaciones más recientes se guardan en el registro. (No existe un límite práctico en Android 8.0 y versiones posteriores).

Para inspeccionar el registro de asignaciones, sigue estos pasos:

  1. Explora la lista para encontrar objetos que tengan recuentos de montón inusualmente elevados y podrían experimentar fugas. Para que te resulte más sencillo encontrar clases conocidas, haz clic en el encabezado de la columna Class Name a fin de ordenarlas alfabéticamente. Luego haz clic en el nombre de una clase. El subpanel Instance View aparecerá a la derecha y en él se mostrará cada instancia de la clase, como puede verse en la figura 3.
  2. En el subpanel Instance View, haz clic en una instancia. La pestaña Call Stack aparecerá debajo y en ella se mostrará el punto en que se asignó esa instancia y el subproceso implicado.
  3. En la pestaña Call Stack, haz clic en cualquier línea para acceder al código en cuestión en el editor.

Figura 3: Aparecen detalles de cada objeto asignado en el subpanel Instance View, a la derecha.

De forma predeterminada, la lista de asignaciones a la izquierda se ordena según el nombre de la clase. En la parte superior de la lista, puedes usar el menú desplegable a la derecha para alternar los siguientes tipos de orden:

Capturar un volcado de montón

Un volcado de montón muestra los objetos de tu app que consumen memoria en el momento en que lo capturas. En particular después de una sesión de usuario extensa, un volcado de montón puede ayudar a identificar fugas de memoria mostrando objetos que todavía están en ella y que , según tu criterio, ya no deberían estar ahí. Cuando captures un volcado de montón, podrás ver lo siguiente:

Figura 4: Vista del volcado de montón.

Para capturar un volcado de montón, haz clic en Dump Java heap en la barra de herramientas de Memory Profiler. Mientras se vuelca el montón, el volumen de memoria Java puede aumentar temporalmente. Esto es normal, ya que el volcado de montón ocurre en el mismo proceso que tu app y requiere memoria para recolectar los datos.

El volcado de montón aparece debajo de la línea de tiempo de memoria y se muestran todos los tipos de clases que contiene, como se muestra en la figura 4.

Nota: Si necesitas ser más preciso respecto del momento en que se crea el volcado, puedes crear un volcado de montón en el punto crítico del código de tu app llamando a dumpHprofData().

Para inspeccionar tu volcado, sigue estos pasos:

  1. Explora la lista para encontrar objetos que tengan recuentos de montón inusualmente elevados y podrían experimentar fugas. Para que te resulte más sencillo encontrar clases conocidas, haz clic en el encabezado de la columna Class Name a fin de ordenarlas alfabéticamente. Luego haz clic en el nombre de una clase. El subpanel Instance View aparecerá a la derecha y en él se mostrará cada instancia de la clase, como puede verse en la figura 5.
  2. En el subpanel Instance View, haz clic en una instancia. La pestaña References aparecerá debajo y en ella se mostrarán todas las referencias al objeto en cuestión.

    También puedes hacer clic en la flecha junto al nombre de la instancia, para ver todos sus campos, y luego en el nombre de un campo para ver todas sus referencias. A su vez, si deseas ver información de la instancia para un campo, haz clic con el botón secundario en él y selecciona Go to Instance.

  3. En la pestaña References, si identificas una referencia que podría tener una fuga de memoria, haz clic con el botón secundario en ella y selecciona Go to Instance. Con esto, se selecciona la instancia correspondiente del volcado de montón y se muestran sus propios datos de instancia.

De forma predeterminada, el volcado de montón no te muestra el seguimiento de pila para cada objeto asignado. Para obtener el seguimiento de pila, debes comenzar a registrar asignaciones de memoria antes de hacer clic en Dump Java heap. Luego, puedes seleccionar una instancia en el subpanel Instance View y ver la pestaña Call Stack junto a la pestaña References, como se muestra en la figura 5. Sin embargo, es posible que algunos objetos se asignen antes de que comiences a registrar las asignaciones, por lo que la pila de llamadas no estará disponible para dichos objetos. Las instancias que sí incluyen una pila de llamadas se indican con la insignia “stack” en el ícono . (Lamentablemente, ya que el seguimiento de pila requiere que registres las asignaciones, actualmente no puedes ver el seguimiento de pila para volcados de montón en Android 8.0).

En el volcado de montón, busca fugas de memoria ocasionadas por alguno de los siguientes elementos:

Figura 5: La duración necesaria para capturar un volcado de montón se indica en la línea de tiempo.

En la lista de clases, puedes ver la siguiente información:

En la parte superior de la lista de clases, puedes usar la lista desplegable de la izquierda para alternar los siguientes volcados de montón:

De forma predeterminada, la lista de objetos del montón se ordena por nombre de clase. Puedes usar el otro menú desplegable para alternar los siguientes tipos de orden:

De forma predeterminada, la lista se ordena mediante la columna Retained Size. Puedes hacer clic en cualquiera de los encabezados de las columnas para cambiar la manera en que se ordena la lista.

En la vista Instance View, cada instancia incluye lo siguiente:

Guardar el volcado de montón como HPROF

Cuando capturas un volcado de montón, los datos pueden verse en Memory Profiler únicamente mientras este se encuentre en ejecución. Cuando sales de la sesión de generación de perfiles, se pierde el vaciado de montón. Por lo tanto, si deseas guardarlo para revisarlo más tarde, exporta el vaciado de montón a un archivo HPROF haciendo clic en Export heap dump as HPROF file , en la barra de herramientas debajo de la línea de tiempo. En el diálogo que aparece, asegúrate de guardar el archivo con el sufijo .hprof.

Luego, puedes reabrir el archivo en Android Studio arrastrándolo y soltándolo en una ventana vacía del editor (o en la barra de la pestaña de archivos).

Para usar un analizador de HPROF como jhat, debes convertir el archivo HPROF del formato de Android al formato SE HPROF de Java. Puedes hacerlo con la herramienta hprof-conv provista en el directorio android_sdk/platform-tools/. Ejecuta el comando hprof-conv con dos argumentos: el archivo HPROF original y la ubicación para escribir el archivo HPROF convertido. Por ejemplo:

hprof-conv heap-original.hprof heap-converted.hprof

Técnicas para generar perfiles de tu memoria

Al usar Memory Profiler, debes forzar el código de tu app e intentar que se produzcan fugas de memoria. Una forma de provocar fugas de memoria en tu app es permitir que esta se ejecute durante un rato antes de inspeccionar el montón. Es posible que las fugas se desplacen hasta la parte superior de las asignaciones en el montón. Sin embargo, cuanto más pequeña sea la fuga, durante más tiempo deberás ejecutar la app para poder verla.

También puedes activar una fuga de memoria de una de las siguientes maneras:

Sugerencia: También puedes realizar los pasos anteriores usando el marco de trabajo de prueba monkeyrunner.

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Sigue a Google Developers en WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (Dec 2017 Android Platform & Tools Survey)