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.
- Android cómo implementar eficientemente el caché de datos y los eventos de cambio de configuración en fragmentos?
- Fuga de memoria durante el uso de anuncios intersticiales de Admob
- Tabla de referencia local de JNI de Android Expand
- OutOfMemoryException en el emulador
- Reciclaje de bitmaps
Quería saber un poco más acerca de qué es eso, así que abrí el árbol dominador y vi esto:
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:
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
ydrawable-xxx
y ejecutar la aplicación sin recursos extraíbles, y elbyte[]
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!
- pérdida de memoria debido a llamada bitmapfactory
- Comprensión onTrimMemory (nivel int)
- Android Universal Image Loader - ¿Cómo configuro las especificaciones correctamente?
- El método android finish () no borra la aplicación de la memoria
- Prueba Android "destruir actividad para ahorrar espacio"
- ¿Puedo obtener la cantidad de memoria que queda para mi programa?
- Analizar la memoria instantánea hprof archivos de índice programmically
- Herramienta para comprobar fugas de memoria en android
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)?
- Condición de carrera entre la aplicación onCreate y los recursos cargados?
- API21 setButtonTintList en CheckBox