Cómo encontrar las estadísticas de uso de memoria real para un teléfono Android

Debido a que Android está diseñado para dispositivos móviles, siempre debe tener cuidado con la cantidad de memoria de acceso aleatorio (RAM) que usa su aplicación. Aunque Dalvik y ART realizan la recolección de basura de rutina (GC), esto no significa que pueda ignorar cuándo y dónde su aplicación asigna y libera memoria. Para proporcionar una experiencia de usuario estable que permita que el sistema cambie rápidamente entre aplicaciones, es importante que su aplicación no consuma memoria innecesariamente cuando el usuario no está interactuando con ella.

Incluso si sigue todas las mejores prácticas para administrar la memoria de su aplicación durante el desarrollo (lo cual debería hacer), aún podría perder objetos o introducir otros errores de memoria. La única forma de asegurarse de que su aplicación esté utilizando la menor cantidad de memoria posible es analizar el uso de memoria de su aplicación con herramientas. Esta guía le muestra cómo hacerlo.

Interpretar mensajes de registro


El lugar más simple para comenzar a investigar el uso de memoria de su aplicación son los mensajes de registro de tiempo de ejecución. A veces, cuando se produce un GC, se imprime un mensaje en logcat. La salida de logcat también está disponible en el Monitor de dispositivo o directamente en un IDE como Android Studio.

Dalvik Log Messages

En Dalvik (pero no ART), cada GC imprime la siguiente información en logcat:

D / dalvikvm: , , ,

Ejemplo:

D / dalvikvm (9050): GC_CONCURRENT liberado 2049K, 65% libre 3571K / 9991K, externo 4703K / 5261K, en pausa 2 ms + 2 ms

Motivo GC

Lo que activó el GC y qué tipo de colección es. Las razones que pueden aparecer incluyen:

GC_CONCURRENT

Un GC concurrente que libera memoria a medida que su montón comienza a llenarse.

GC_FOR_MALLOC

Se produjo un GC porque su aplicación intentó asignar memoria cuando su montón ya estaba lleno, por lo que el sistema tuvo que detener su aplicación y reclamar memoria.

GC_HPROF_DUMP_HEAP

Un GC que se produce cuando solicita crear un archivo HPROF para analizar su montón.

GC_EXPLICIT

Un GC explícito, como cuando llama a gc () (que debe evitar llamar y confiar en que el GC se ejecute cuando sea necesario).

GC_EXTERNAL_ALLOC

Esto sucede solo en el nivel 10 de API y versiones inferiores (las versiones más nuevas asignan todo en el montón de Dalvik). Un GC para memoria asignada externamente (como los datos de píxeles almacenados en la memoria nativa o las memorias intermedias de bytes NIO).

Cantidad liberada

La cantidad de memoria recuperada de este GC.

Estadísticas de montón

Porcentaje libre del montón y (número de objetos vivos) / (tamaño total del montón).

Estadísticas de memoria externa

Memoria asignada externamente en el nivel API 10 y menor (cantidad de memoria asignada) / (límite en el que se realizará la recopilación).

Tiempo de pausa

Los montones más grandes tendrán tiempos de pausa más largos. Los tiempos de pausa concurrentes muestran dos pausas: una al comienzo de la colección y otra cerca del final.

A medida que se acumulan estos mensajes de registro, busque aumentos en las estadísticas de 3571K/9991K dinámico (el valor 3571K/9991K en el ejemplo anterior). Si este valor continúa aumentando, es posible que tenga una pérdida de memoria.

Mensajes de registro de ART

A diferencia de Dalvik, ART no registra mensajes para GC que no se solicitaron explícitamente. Los GC solo se imprimen cuando se consideran lentos. Más precisamente, si la pausa del GC supera los 5 ms o la duración del GC supera los 100 ms. Si la aplicación no está en un estado de proceso perceptible de pausa, entonces ninguno de sus GC se considera lento. Los GC explícitos siempre se registran.

ART incluye la siguiente información en sus mensajes de registro de recolección de basura:

I / art: () AllocSpace Objects, () LOS objetos,

Ejemplo:

I / art: barrido de marca concurrente explícito GC liberado 104710 (7MB) objetos AllocSpace, 21 (416KB) objetos LOS, 33% gratis, 25MB / 38MB, pausado 1.230ms total 67.216ms

Motivo GC

Lo que activó el GC y qué tipo de colección es. Las razones que pueden aparecer incluyen:

Concurrent

Un GC concurrente que no suspende hilos de aplicaciones. Este GC se ejecuta en un subproceso en segundo plano y no impide las asignaciones.

Alloc

El 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 se produjo en el subproceso de asignación.

Explicit

La recolección de basura fue solicitada explícitamente por una aplicación, por ejemplo, llamando a gc () o gc (). Al igual que con Dalvik, en ART se recomienda que confíe en el GC y evite solicitar GC explícitos si es posible. Se desaconsejan los GC explícitos ya que bloquean el subproceso de asignación e innecesariamente eran ciclos de CPU. Los GC explícitos también pueden causar jank si provocan que otros subprocesos sean reemplazados.

NativeAlloc

La colección fue causada por la presión de la memoria nativa de las asignaciones nativas, como los mapas de bits o los objetos de asignación RenderScript.

CollectorTransition

La colección fue causada por una transición de montón; esto es causado por cambiar el GC en tiempo de ejecución. Las transiciones de recopilador consisten en copiar todos los objetos de un espacio respaldado por una lista libre en un espacio de puntero (o viceversa). Actualmente, las transiciones de recopilador solo ocurren cuando una aplicación cambia los estados de proceso de un estado perceptible de pausa a un estado perceptible sin pausa (o viceversa) en dispositivos con poca RAM.

HomogeneousSpaceCompact

La compactación de espacio homogénea es espacio de lista libre a espacio de lista libre que generalmente ocurre cuando una aplicación se mueve a un estado de proceso imperceptible en pausa. Las principales razones para hacerlo son reducir el uso de RAM y desfragmentar el montón.

DisableMovingGc

Esta no es una razón real de GC, sino una nota de que la colección se bloqueó debido al uso de GetPrimitiveArrayCritical. mientras se produce la compactación simultánea del montón. En general, se desaconseja el uso de GetPrimitiveArrayCritical debido a sus restricciones para mover colectores.

HeapTrim

Esta no es una razón de GC, sino una nota de que la colección se bloqueó hasta que finalizó un recorte de montón.

Nombre de GC

ART tiene varios GC diferentes que pueden ejecutarse.

Concurrent mark sweep (CMS)

Un recopilador de montón completo que libera recopila todos los espacios que no sean el espacio de la imagen.

Concurrent partial mark sweep

Un recopilador de montón en su mayoría completo que recoge todos los espacios que no sean la imagen y los espacios de cigoto.

Concurrent sticky mark sweep

Un colector generacional que solo puede liberar objetos asignados desde el último GC. Esta recolección de basura se ejecuta con más frecuencia que un barrido de marcas completo o parcial, ya que es más rápido y tiene pausas más bajas.

Marksweep + semispace

Un GC de copia no concurrente utilizado para transiciones de montón, así como la compactación de espacio homogéneo (para defraudar el montón).

Objetos liberados

El número de objetos que se recuperaron de este GC desde el espacio de objetos no grandes.

Tamaño liberado

El número de bytes que se recuperaron de este GC desde el espacio de objetos no grandes.

Grandes objetos liberados

El número de objetos en el espacio de objetos grandes que se recuperaron de esta recolección de basura.

Tamaño de objeto grande liberado

El número de bytes en el espacio de objetos grandes que se recuperaron de esta recolección de basura.

Estadísticas de montón

Porcentaje libre y (número de objetos vivos) / (tamaño de almacenamiento dinámico total).

Tiempos de pausa

En general, los tiempos de pausa son proporcionales al número de referencias de objetos que se modificaron mientras se ejecutaba el GC. Actualmente, los GC ART CMS solo tienen una pausa, cerca del final del GC. Los GC en movimiento tienen una pausa larga que dura la mayor parte de la duración del GC.

Si está viendo una gran cantidad de GC en logcat, busque aumentos en las estadísticas de 25MB/38MB dinámico (el valor de 25MB/38MB en el ejemplo anterior). Si este valor continúa aumentando y parece que nunca disminuye, podría tener una pérdida de memoria. Alternativamente, si está viendo GC que son por la razón “Alloc”, entonces ya está operando cerca de su capacidad de almacenamiento dinámico y puede esperar excepciones OOM en el futuro cercano.

Visualización de actualizaciones de montón


Para obtener un poco de información sobre qué tipo de memoria usa su aplicación y cuándo, puede ver las actualizaciones en tiempo real del montón de su aplicación en el visor HPROF de Android Studio o en el Monitor de dispositivo:

Monitor de memoria en Android Studio

Use Android Studio para ver el uso de memoria de su aplicación:

  1. Inicie su aplicación en un dispositivo o emulador conectado.
  2. Abra la ventana de tiempo de ejecución de Android y vea la memoria libre y asignada en el Monitor de memoria.
  3. Haga clic en el ícono Dump Java Heap () en la barra de herramientas del Monitor de memoria. Android Studio crea el archivo de instantánea del montón con el nombre de archivo .ss.hprof en la pestaña Capturas .
  4. Haga doble clic en el archivo de instantánea del montón para abrir el visor HPROF. Nota: Para convertir un volcado de almacenamiento dinámico al formato HPROF estándar en Android Studio, haga clic con el botón derecho en una instantánea de almacenamiento dinámico en la vista Capturas y seleccione Exportar a .hprof estándar .
  5. Interactúe con su aplicación y haga clic en el ícono () para causar la asignación del montón.
  6. Identifique qué acciones en su aplicación probablemente causen demasiada asignación y determine en qué parte de su aplicación debería intentar reducir las asignaciones y liberar recursos.

Monitor de dispositivo

  1. Abra el Monitor del dispositivo. Desde su directorio /tools/ , inicie la herramienta del monitor .
  2. En la ventana Monitor de depuración, seleccione el proceso de su aplicación de la lista de la izquierda.
  3. Haga clic en Actualizar montón encima de la lista de procesos.
  4. En el panel del lado derecho, seleccione la pestaña Montón .

La vista del montón muestra algunas estadísticas básicas sobre el uso de la memoria del montón, actualizadas después de cada GC. Para ver la primera actualización, haga clic en el botón Causa GC .

Figura 1. La herramienta Monitor de dispositivo, que muestra los botones [1] Actualizar montón y [2] Causa GC . La pestaña Montón a la derecha muestra los resultados del montón.

Continúe interactuando con su aplicación para ver la actualización de su asignación de montón con cada recolección de basura. Esto puede ayudarlo a identificar qué acciones en su aplicación probablemente causen demasiada asignación y dónde debe intentar reducir las asignaciones y liberar recursos.

Seguimiento de asignaciones


A medida que empiece a reducir los problemas de memoria, también debe usar el Rastreador de asignación para obtener una mejor comprensión de dónde se asignan los objetos que acaparan la memoria. El Rastreador de asignación puede ser útil no solo para analizar usos específicos de la memoria, sino también para analizar rutas de código críticas en una aplicación, como el desplazamiento.

Por ejemplo, el seguimiento de las asignaciones al arrojar una lista en su aplicación le permite ver todas las asignaciones que deben hacerse para ese comportamiento, en qué hilo están y de dónde provienen. Esto es extremadamente valioso para ajustar estos caminos para reducir el trabajo que necesitan y mejorar la suavidad general de la interfaz de usuario.

Para usar el Rastreador de asignación, abra el Monitor de memoria en Android Studio y haga clic en el icono Rastreador de asignación. También puede realizar un seguimiento de las asignaciones en el Monitor de dispositivo Android:

Android Studio

Para usar el Rastreador de asignación en Android Studio:

  1. Inicie su aplicación en un dispositivo o emulador conectado
  2. Abra la ventana de ejecución de Android y vea la memoria libre y asignada en el Monitor de memoria.
  3. Haga clic en el icono del Rastreador de asignación () en la barra de herramientas del Monitor de memoria para iniciar y detener las asignaciones de memoria. Android Studio crea el archivo de asignación con el nombre de archivo http://Allocations-yyyy.mm.dd-hh.mm .ss.alloc en Pestaña de capturas .
  4. Haga doble clic en el archivo de asignación para abrir el visor de asignación.
  5. Identifique qué acciones en su aplicación probablemente causen demasiada asignación y determine en qué parte de su aplicación debería intentar reducir las asignaciones y liberar recursos.
  6. Monitor de dispositivo
  7. Abra el Monitor del dispositivo. Desde su directorio /tools/ , inicie la herramienta del monitor .
  8. En la ventana DDMS, seleccione el proceso de su aplicación en el panel del lado izquierdo.
  9. En el panel del lado derecho, seleccione la pestaña Rastreador de asignación .
  10. Haga clic en Iniciar seguimiento .
  11. Interactúe con su aplicación para ejecutar las rutas de código que desea analizar.
  12. Haga clic en Obtener asignaciones cada vez que desee actualizar la lista de asignaciones.

La lista muestra todas las asignaciones recientes, actualmente limitadas por un buffer de anillo de 512 entradas. Haga clic en una línea para ver el seguimiento de la pila que condujo a la asignación. El seguimiento muestra no solo qué tipo de objeto se asignó, sino también en qué hilo, en qué clase, en qué archivo y en qué línea.

Figura 2. La herramienta Monitor de dispositivo, que muestra las asignaciones de aplicaciones recientes y los seguimientos de pila en el Rastreador de asignación.

Nota: Siempre verá algunas asignaciones de DdmVmInternal y de otros lugares que provienen del rastreador de asignaciones.

Aunque no es necesario (ni posible) eliminar todas las asignaciones de las rutas de código críticas de rendimiento, el rastreador de asignación puede ayudarlo a identificar problemas importantes en su código. Por ejemplo, algunas aplicaciones pueden crear un nuevo objeto Paint en cada dibujo. Mover ese objeto a un miembro global es una solución simple que ayuda a mejorar el rendimiento.

Ver asignaciones generales de memoria


Para un análisis más detallado, es posible que desee observar cómo se divide la memoria de su aplicación entre diferentes tipos de asignación de RAM con el siguiente comando adb:

adb shell dumpsys meminfo [-d]

La bandera -d imprime más información relacionada con Dalvik y el uso de memoria ART.

La salida enumera todas las asignaciones actuales de su aplicación, medidas en kilobytes.

Al inspeccionar esta información, debe estar familiarizado con los siguientes tipos de asignación:

RAM privada (limpia y sucia)

Esta es la memoria que está siendo utilizada solo por su proceso. Esta es la mayor parte de la RAM que el sistema puede reclamar cuando se destruye el proceso de su aplicación. En general, la parte más importante de esto es la RAM “privada sucia”, que es la más costosa porque solo la usa su proceso 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 almacenamiento dinámico de Dalvik y nativas que realice serán RAM sucias privadas; Dalvik y las asignaciones nativas que comparte con el proceso Zygote son RAM sucias compartidas.

Tamaño de conjunto proporcional (PSS)

Esta es una medida del uso de RAM de su aplicación que tiene en cuenta el intercambio de páginas entre procesos. Las páginas RAM que son exclusivas de su proceso contribuyen directamente a su valor de PSS, mientras que las páginas que se comparten con otros procesos contribuyen al valor de PSS solo en proporción a la cantidad de uso compartido. Por ejemplo, una página que se comparte entre dos procesos contribuirá con la mitad de su tamaño al PSS de cada proceso.

Una buena característica de la medición de PSS es que puede sumar el PSS en todos los procesos para determinar la memoria real utilizada por todos los procesos. Esto significa que PSS es una buena medida para el peso real de RAM de un proceso y para compararlo con el uso de RAM de otros procesos y el total de RAM disponible.

Por ejemplo, a continuación se muestra la salida para el proceso de Map en un dispositivo Nexus 5. Aquí hay mucha información, pero los puntos clave para la discusión se enumeran a continuación.

adb shell dumpsys meminfo com.google.android.apps.maps -d

Nota: La información que ve puede variar ligeramente de lo que se muestra aquí, ya que algunos detalles del resultado difieren entre las versiones de la plataforma.

** MEMINFO en 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 Otro 972 972 0 0 Pila 1144 1144 0 0 Gfx dev 35300 35300 0 0 Otro 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 Otros mmap 30 4 0 0 EGL mtrack 73072 73072 0 0 GL mtrack 51044 51044 0 0 Desconocido 185 184 0 0 TOTAL 216524 208232 4384 0 82916 68345 14570 Dalvik Detalles .Heap 6568 6568 0 0 .LOS 24771 24404 0 0 .GC 500500 0 0 .JITCache 428 428 0 0 .Zygote 1093 936 0 0 .NonMoving 1908 1908 0 0. IndirectRef 44 44 0 0 Objetos Vistas: 90 ViewRootImpl: 1 AppContexts: 4 Actividades: 1 Activos: 2 AssetManagers: 2 Carpetas locales: 21 Carpetas de proxy: 28 Memoria de paquetes: 18 Conteo de paquetes: 74 Destinatarios de la muerte: 2 Socketes OpenSSL ts: 2

Aquí hay un dumpsys anterior en Dalvik de la aplicación de gmail:

** MEMINFO en pid 9953 [http://com.google.android.gm] ** Pss Pss Compartido Privado Compartido Privado Montón Montón Total Limpio Sucio Sucio Limpio Limpio Tamaño Alloc Libre —— —— —— —— —— – – —— —— —— 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 Otro 2850 0 2684 2772 0 0 Pila 36 0 8 36 0 0 Cursor 136 0 0 136 0 0 Ashmem 12 0 28 0 0 0 Otros 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) Otros mmap 107 0 8 8 324 68 Desconocido 6994 (4) 0 252 6992 (4) 0 0 TOTAL 24358 (1) 4188 9724 17972 (2) 16388 4260 (2) 16968 16595 336 Vistas de objetos: 426 ViewRootImpl: 3 (8) AppContexts: 6 (7) Actividades: 2 (7) Activos: 2 AssetManagers: 2 Carpetas locales: 64 Carpetas de proxy: 34 Destinatarios de la muerte: 0 Sockets OpenSSL: 1 SQL MEMORY_USED: 1739 PAGECACHE_OVERFLOW: 1164 MALLOC_SIZE: 62

En general, debe preocuparse solo por las columnas Pss Total y Private Dirty . En algunos casos, las columnas Private Clean y Heap Alloc también ofrecen datos interesantes. Aquí hay más información sobre las diferentes asignaciones de memoria (las filas) que debe observar:

Dalvik Heap

La RAM utilizada por las asignaciones de Dalvik en su aplicación. El Pss Total incluye todas las asignaciones de cigoto (ponderadas por su intercambio entre procesos, como se describe en la definición de PSS anterior). El número Private Dirty es la RAM real comprometida solo con el montón de su aplicación, compuesta por sus propias asignaciones y cualquier página de asignación de Zygote que se haya modificado desde que bifurcó el proceso de su aplicación desde Zygote.

Nota: en las versiones de plataforma más nuevas que tienen la sección Dalvik Other , los números Pss Total y Private Dirty para Dalvik Heap no incluyen los gastos generales de Dalvik, como la compilación just-in-time (JIT) y la contabilidad de GC, mientras que las versiones anteriores lo enumeran todo combinado bajo Dalvik .

Heap Alloc es la cantidad de memoria que Dalvik y los asignadores de almacenamiento dinámico nativos realizan un seguimiento de su aplicación. Este valor es mayor que Pss Total y Private Dirty porque su proceso se bifurcó de Zygote e incluye asignaciones que su proceso comparte con todos los demás.

.so mmap y .dex mmap

La RAM que se usa para el código asignado .so (nativo) y .dex (Dalvik o ART). El número Pss Total incluye código de plataforma compartido entre aplicaciones; Private Clean es el código de su aplicación. En general, el tamaño mapeado real será mucho mayor: la RAM aquí es solo la que necesita estar actualmente en la RAM para el código que ha sido ejecutado por la aplicación. Sin embargo, el .so mmap tiene una gran suciedad privada, que se debe a arreglos en el código nativo cuando se cargó en su dirección final.

.oat mmap

Esta es la cantidad de RAM utilizada por la imagen del código que se basa en las clases precargadas que suelen utilizar varias aplicaciones. Esta imagen se comparte en todas las aplicaciones y no se ve afectada por aplicaciones particulares.

.art mmap

Esta es la cantidad de RAM utilizada por la imagen del montón que se basa en las clases precargadas que suelen utilizar varias aplicaciones. Esta imagen se comparte en todas las aplicaciones y no se ve afectada por aplicaciones particulares. Aunque la imagen ART contiene instancias de objeto, no cuenta para el tamaño de su montón.

.Heap (solo con la .Heap -d)

Esta es la cantidad de memoria de almacenamiento dinámico para su aplicación. Esto excluye los objetos en la imagen y los espacios de objetos grandes, pero incluye el espacio del cigoto y el espacio sin movimiento.

.LOS (solo con el indicador -d)

Esta es la cantidad de RAM utilizada por el espacio de objetos grandes de ART. Esto incluye cigoto objetos grandes. Los objetos grandes son todas las asignaciones de matrices primitivas mayores de 12 KB.

.GC (solo con el .GC -d)

Esta es la cantidad de gastos generales de contabilidad de GC internos para su aplicación. Realmente no hay ninguna manera de reducir esta sobrecarga.

.JITCache (solo con el .JITCache -d)

Esta es la cantidad de memoria utilizada por los datos JIT y las memorias caché de código. Por lo general, esto es cero ya que todas las aplicaciones se compilarán en el momento de la instalación.

.Zygote (solo con la bandera -d)

Esta es la cantidad de memoria utilizada por el espacio del cigoto. El espacio de cigoto se crea durante el inicio del dispositivo y nunca se asigna a.

.NonMoving (solo con la bandera -d)

Esta es la cantidad de RAM utilizada por el espacio no móvil ART. El espacio no móvil contiene objetos especiales que no se pueden mover, como campos y métodos. Puede reducir esta sección utilizando menos campos y métodos en su aplicación.

.IndirectRef (solo con el indicador -d)

Esta es la cantidad de RAM utilizada por las tablas de referencia indirecta ART. Por lo general, esta cantidad es pequeña, pero si es demasiado alta, es posible reducirla reduciendo el número de referencias JNI locales y globales utilizadas.

Unknown

Cualquier página RAM que el sistema no pueda clasificar en uno de los otros elementos más específicos. Actualmente, esto contiene principalmente asignaciones nativas, que la herramienta no puede identificar cuando se recopilan estos datos debido a la asignación aleatoria del diseño del espacio de direcciones (ASLR). Al igual que con el montón de Dalvik, el Pss Total for Unknown tiene en cuenta el uso compartido con Zygote, y Private Dirty es una RAM desconocida dedicada solo a su aplicación.

TOTAL

La RAM total del tamaño de conjunto proporcional (PSS) utilizada por su proceso. Esta es la suma de todos los campos de PSS por encima. Indica el peso total de la memoria de su proceso, que se puede comparar directamente con otros procesos y la RAM total disponible.

Private Dirty y Private Clean son las asignaciones totales dentro de su proceso, que no se comparten con otros procesos. Juntos (especialmente Private Dirty ), esta es la cantidad de RAM que se liberará al sistema cuando se destruya su proceso. RAM sucia son páginas que se han modificado y, por lo tanto, deben permanecer comprometidas con la RAM (porque no hay intercambio); RAM limpia son páginas que se han mapeado desde un archivo persistente (como el código que se está ejecutando) y, por lo tanto, se pueden eliminar si no se usan durante un tiempo.

ViewRootImpl

El número de vistas raíz que están activas en su proceso. Cada vista raíz está asociada con una ventana, por lo que puede ayudarlo a identificar pérdidas de memoria que involucran cuadros de diálogo u otras ventanas.

AppContexts y Activities

El número de objetos de contexto y actividad de la aplicación que actualmente viven en su proceso. Esto puede ser útil para identificar rápidamente los objetos de actividad filtrados que no se pueden recolectar basura debido a referencias estáticas en ellos, lo cual es común. Estos objetos a menudo tienen muchas otras asignaciones asociadas y, por lo tanto, son una buena manera de rastrear grandes pérdidas de memoria.

Nota: Una vista o un objeto dibujable también contiene una referencia a la actividad de la que proviene, por lo que sostener una vista o un objeto dibujable también puede hacer que su aplicación filtre una actividad.

Capturando un basurero


Un volcado de almacenamiento dinámico es una instantánea de todos los objetos en el almacenamiento dinámico de su aplicación, almacenados en un formato binario llamado HPROF. El volcado de almacenamiento dinámico de su aplicación proporciona información sobre el estado general del almacenamiento dinámico de su aplicación para que pueda rastrear los problemas que podría haber identificado al ver las actualizaciones de almacenamiento dinámico.

Para recuperar su volcado de montón desde Android Studio, use el Monitor de memoria y el visor HPROF.

También puede realizar estos procedimientos en el monitor de Android:

  1. Abra el Monitor del dispositivo. Desde su directorio /tools/ , inicie la herramienta del monitor .
  2. En la ventana DDMS, seleccione el proceso de su aplicación en el panel del lado izquierdo.
  3. Haga clic en Volcar archivo HPROF , como se muestra en la figura 3.
  4. En la ventana que aparece, asigne un nombre a su archivo HPROF, seleccione la ubicación de guardado y luego haga clic en Guardar .

Figura 3. La herramienta Monitor de dispositivo, que muestra el botón [1] Volcar archivo de HPROF .

Si necesita ser más preciso sobre cuándo se crea el volcado, también puede crear un volcado de montón en el punto crítico en el código de su aplicación llamando a dumpHprofData ().

El volcado del montón se proporciona en un formato similar, pero no idéntico al de la herramienta Java HPROF. La principal diferencia en un volcado de almacenamiento dinámico de Android se debe al hecho de que hay una gran cantidad de asignaciones en el proceso Zygote. Pero debido a que las asignaciones de Zygote se comparten en todos los procesos de la aplicación, no son muy importantes para su propio análisis de montón.

Para analizar su volcado de almacenamiento dinámico, puede usar Memory Monitor en Android Studio. También puede usar una herramienta estándar como jhat. Sin embargo, primero deberá convertir el archivo HPROF del formato de Android al formato J2SE HPROF. Puede hacerlo utilizando la herramienta hprof-conv provista en el directorio /platform-tools/ . Simplemente ejecute el 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-convertido.hprof

Ahora puede cargar el archivo convertido en una herramienta de análisis de montón que comprende el formato J2SE HPROF.

Al analizar su montón, debe buscar pérdidas de memoria causadas por:

  • Referencias de larga duración a una actividad, contexto, vista, dibujable y otros objetos que pueden contener una referencia a la actividad o contexto del contenedor.
  • Clases internas no estáticas (como Runnable, que puede contener la instancia de Activity).
  • Cachés que contienen objetos por más tiempo del necesario.

Disparando fugas de memoria


Al usar las herramientas descritas anteriormente, debe enfatizar agresivamente el código de su aplicación e intentar forzar las pérdidas de memoria. Una forma de provocar pérdidas de memoria en su aplicación es dejarla funcionar durante un tiempo antes de inspeccionar el montón. Las fugas se filtrarán hasta la parte superior de las asignaciones en el montón. Sin embargo, cuanto menor sea la fuga, más tiempo necesitará ejecutar la aplicación para poder verla.

También puede desencadenar una pérdida de memoria de una de las siguientes maneras:

  1. Gire el dispositivo de vertical a horizontal y viceversa varias veces mientras esté en diferentes estados de actividad. Girar el dispositivo a menudo puede hacer que una aplicación pierda un objeto Actividad, Contexto o Vista porque el sistema recrea la Actividad y si su aplicación tiene una referencia a uno de esos objetos en otro lugar, el sistema no puede recolectar basura.
  2. Cambie entre su aplicación y otra aplicación mientras se encuentra en diferentes estados de actividad (navegue a la pantalla de Inicio, luego regrese a su aplicación).

Sugerencia: También puede realizar los pasos anteriores utilizando el marco de prueba “mono”. Para obtener más información sobre cómo ejecutar el marco de prueba de mono, lea la documentación demonkeyrunner.

Bueno, ahí está tu problema; Estás viendo el uso. Memoria significa RAM. Esa es la cantidad de RAM que se usa en su teléfono. Lo que estás buscando es almacenamiento. La forma de encontrar esto varía, pero generalmente puede buscar en “aplicaciones” en la configuración. También puede intentar verificar el tamaño de su carpeta raíz.