Enorme byte en mi aplicación después de HPROF

De vez en cuando, especialmente al implementar nuevas funcionalidades en mi aplicación, uso DDMS + HPROF para analizar la memoria y el uso de montón. Como la aplicación no parece tener problemas de rendimiento ANR y todo funciona bien, inicialmente no me importaba, pero ahora, como veo es aproximadamente siempre el mismo tamaño, me pregunto qué diablos puede ser.

Cada vez que ejecuto un HPROF, comprobar la pestaña de sospechosos de fugas . Siempre hay una instancia de android.graphics.Bitmap que toma aproximadamente el 25% de todo el montón utilizado.

Sospechosos de fugas

Quería saber un poco más acerca de qué es eso, así que abrí el árbol dominador y vi esto:

Árbol dominador

Tan esentially hay una instancia de byte[] enorme que está reteniendo un montón de montón, y nunca se libera. De acuerdo con esto , copié el valor de ese byte[] , lo .data un archivo .data , se abrió con Gimp, y ahí está el resultado:

PNG

Así que básicamente, se parece a la parte "alfa (0)" de una imagen PNG. Teniendo en cuenta los siguientes hechos:

  • Todos mis archivos de imagen tienen un tamaño <8K
  • Sólo algunos de ellos son PNG – el resto que pude convertir a JPG, lo hice
  • No importa si agrego más imágenes, el tamaño de ese byte[] siempre ha sido aproximadamente el mismo desde el principio de la aplicación (hace 4 meses)
  • Para depurarlo, intenté quitar cualquier archivo de imagen de las carpetas drawable y drawable-xxx y ejecutar la aplicación sin recursos extraíbles, y el byte[] todavía estaba allí
  • Quité casi todos los diseños y dejé que la funcionalidad básica, y el mismo resultado
  • En el árbol Dominator , la clase raíz es android.graphics.Bitmap

Alguien sabe lo que este byte[] y si debo hacer algo para liberarlo?

¡Cualquier ayuda apreciada!

Sólo para aclarar algunas cosas:

  • Las imágenes / dibujos en tu aplicación se utilizan en la memoria en forma de android.graphics.Bitmap .
  • A partir de Android 3.0 (API nivel 11), los datos de píxeles se almacenan en el montón de Dalvik junto con el mapa de bits asociado. ( Gestión de memoria de mapa de bits )
  • "Enorme byte []" es probablemente una exageración ya que es poco más de 1 MB de espacio de montón.

El informe de Sospechos de fugas puede ser útil, pero en este caso no le está diciendo mucho teniendo en cuenta que su sospechoso más grande es algo más de 1MB de memoria. Los dispositivos modernos están ofreciendo 64MB + montones.

Hagamos las matemáticas para los requisitos de memoria para este mapa de bits. Este mapa de bits está ocupando 1.127.584 bytes en el montón. Si asumiéramos que este mapa de bits se configura utilizando ARGB_8888, cada píxel utiliza 4 bytes, lo que significa que su imagen contiene 281.896 píxeles (o aproximadamente 530×530). ¿Esto suena razonable para lo que estás haciendo?

También, considere la forma en que Android se desplaza a través de los diferentes "cubos" para los elementos estirables: mdpi, hdpi, xhdpi, etc. Digamos que tiene una imagen 200×200 en el cubo mdpi y está abriendo la aplicación en un dispositivo xhdpi . Esta imagen será escalada para ser dos veces más grande y tendrá una resolución en el dispositivo de 400×400. Así, mientras que la imagen 200×200 puede no tener mucho espacio de montón (200 x 200 x 4 = 160 kb ), la imagen 400×400 requerirá una cantidad relativamente mayor (4x) de espacio de montón (400 x 400 x 4 = 640 kb ). Para obtener más información al respecto, consulte Soporte de varias pantallas .

Una buena herramienta para calcular rápidamente las diferencias con los cubos de imagen: Android DPI Calculator

Dijiste que eliminaste algunos de tus dibujos, pero ¿qué queda? ¿Ha pensado en los elementos extraíbles que pueden provenir de bibliotecas externas?

Para responder a su pregunta final: ¿ Alguien sabe lo que este byte [] y si debo hacer algo para liberarlo?

Yo diría: Esta pequeña cantidad de memoria en su montón no es nada de lo que preocuparse. Si te molesta, vigila y asegúrate de que no esté creciendo más allá de lo que parece práctico. Si sigue sospechando una pérdida de memoria, navegue entre las pantallas y observe para ver si el montón sigue creciendo. Suponiendo que no esté almacenando en caché los mapas de bits, el montón debe mantener un tamaño consistente / predecible al navegar hacia adelante y hacia atrás entre dos pantallas

Como una nota lateral, DDMS hace que sea muy fácil de monitorear el tamaño del montón sobre la marcha. No hay necesidad de vertederos de HPROF hasta que esté listo para sumergirse. Eche un vistazo a Uso de DDMS . Tome especial nota del botón "Causa GC" ya que será necesario para activar la actualización del tamaño del montón inicial.

ACTUALIZACIÓN

Para responder a esto, una sospecha no apoyada que tengo es que algunos de los activos de la aplicación (activos del sistema / texturas?) Se cargan en el espacio de memoria de su aplicación. Echa un vistazo a la diapositiva 64 aquí: ¿Qué hay de nuevo en Android 4.4 .

Android 4.4 ahora genera una sola textura que contiene todos los activos del marco compartido por todos los procesos. Esto ahorra un poco de memoria en cada proceso, pero también ayuda a dosificar y fusionar operaciones de dibujo para optimizar las aplicaciones automáticamente.

Esto parece implicar que la memoria se utiliza para mapas de bits del sistema / drawables en cada aplicación que ejecuta una versión anterior a 4.4. Si este es el caso, me pregunta si este 1 MB es ese espacio. Me pregunto si podría ejecutar su aplicación en un dispositivo 4.4 / emulador y ver si la misma memoria se utiliza.

Como otra prueba, ¿ha intentado inspeccionar el uso de memoria en una aplicación de barebones (todos los drawables eliminados, etc)?

  • Android Eclipse DDMS> Heap> Causa gris de GC
  • ¿Por qué Android no limpia la memoria después de terminar la actividad?
  • Máxima memoria nativa que se puede asignar a una aplicación para Android
  • ¿Cómo liberar la memoria del objeto Activity real después de dejar la actividad?
  • OutOfMemoryError al escribir en el archivo SharedPreferences
  • Pasar Actividad Contexto para que los constructores lo utilicen internamente - ¿es esto malo?
  • ¿Por qué tengo fugas de memoria cuando estoy haciendo simpy setContentView (R.layout.somelayout)?
  • Límite de tamaño de Android montón, todavía tenemos necesidad de diseñar aplicaciones con un límite de 16 MB en mente?
  • Uso de la memoria V8
  • Callback de Android: ¿es una posible pérdida de memoria?
  • Limpiar la memoria del montón para Excepción de memoria perdida
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.