outofmemoryerror glide example ejemplo java android image performance bitmap

java - glide - Bitmap.Config.HARDWARE vs Bitmap.Config.RGB_565



bitmapfactory options example (1)

API 26 agrega la nueva opción Bitmap.Config.HARDWARE :

Configuración especial, cuando el mapa de bits se almacena solo en la memoria gráfica. Los mapas de bits en esta configuración son siempre inmutables. Es óptimo para los casos, cuando la única operación con el mapa de bits es dibujarlo en una pantalla.

Preguntas que no están explicadas en los documentos:

  1. ¿Debemos SIEMPRE preferir ahora ahora Bitmap.Config.HARDWARE sobre Bitmap.Config.RGB_565 cuando la velocidad es de máxima prioridad y la calidad y la mutabilidad no lo son (por ejemplo, para miniaturas, etc.)?
  2. ¿Los datos de píxeles después de la decodificación con esta opción NO consumen NINGUNA memoria de pila y residen solo en la memoria de la GPU? Si es así, esto parece ser finalmente un alivio para la preocupación de OutOfMemoryException cuando se trabaja con imágenes.
  3. ¿Qué calidad comparamos con RGB_565, RGBA_F16 o ARGB_8888 que podemos esperar de esta opción?
  4. ¿La velocidad de decodificación en sí misma / mejor / vale en comparación con la decodificación con RGB_565?
  5. (Gracias a @CommonsWare por señalarlo en los comentarios) ¿Qué pasaría si superamos la memoria de la GPU al descodificar una imagen con esta opción? ¿Se lanzaría alguna excepción (quizás la misma OutOfMemoryException :)?

La documentación y el código fuente público aún no se han enviado al git de Google . Así que mi investigación se basa solo en información parcial, algunos experimentos y en mi propia experiencia al trasladar JVM a varios dispositivos.

Mi prueba creó un gran mapa de bits modificable y lo copió en un nuevo mapa de bits de HARDWARE con solo hacer clic en un botón, y lo agregó a una lista de mapas de bits. Me las arreglé para crear varias instancias de los mapas de bits grandes antes de que se estrellara.

Pude encontrar esto en el impulso de git de android-o-preview-4 :

+struct AHardwareBuffer; +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer); +#else +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const struct AHardwareBuffer *buffer);

Y buscando la documentación de AHardwareBuffer , bajo el capó está creando un EGLClientBuffer respaldado por ANativeWindowBuffer (buffer gráfico nativo) en la memoria compartida de Android ("ashmem"). Pero la implementación real puede variar a través del hardware.

En cuanto a las preguntas:

  1. ¿Deberíamos SIEMPRE preferir ahora Bitmap.Config.HARDWARE sobre Bitmap.Config.RGB_565 ...?

Para SDK> = 26, la configuración de HARDWARE puede mejorar el dibujo de mapa de bits de bajo nivel al evitar la necesidad de copiar los datos de píxeles a la GPU cada vez que el mismo mapa de bits vuelve a la pantalla. Supongo que puede evitar la pérdida de algunos cuadros cuando se agrega un mapa de bits a la pantalla.

La memoria no se cuenta en su aplicación, y mi prueba confirmó esto.

Los documentos de la biblioteca nativa dicen que devolverá el null si la asignación de memoria no tuvo éxito. Sin el código fuente, no está claro qué hará la implementación de Java (los implementadores de la API) en este caso; podría decidir lanzar la OutOfMemoryException o un OutOfMemoryException a un tipo diferente de asignación.

Actualización: el experimento revela que no se produce una excepción OutOfMemoryException. Si bien la asignación es exitosa, todo funciona bien. Tras la asignación fallida, el emulador se bloqueó (simplemente desapareció). En otras ocasiones, tengo una extraña NullPointerException al asignar Bitmap en la memoria de la aplicación.

Debido a la estabilidad impredecible, no recomendaría usar esta nueva API en producción actualmente . Al menos no sin pruebas exhaustivas.

  1. ¿Los datos de píxeles después de la decodificación con esta opción NO consumen NINGUNA memoria de pila y residen solo en la memoria de la GPU? Si es así, esto parece ser finalmente un alivio para la preocupación de OutOfMemoryException cuando se trabaja con imágenes.

Los datos de píxeles estarán en la memoria compartida (probablemente en la memoria de texturas), pero todavía habrá un pequeño objeto de Bitmap en Java que lo referenciará (por lo que "CUALQUIER" es inexacto).

Cada proveedor puede decidir implementar la asignación real de manera diferente, no es una API pública a la que están obligados. Así que la OutOfMemoryException todavía puede ser un problema. No estoy seguro de cómo se puede manejar correctamente.

  1. ¿Qué calidad en comparación con RGB_565 / ARGB_8888?

La HARDWARE no tiene que ver con la calidad, sino con la ubicación de almacenamiento de píxeles. Dado que los indicadores de configuración no pueden ser OR -ed, supongo que el valor predeterminado ( ARGB_8888 ) se utiliza para la decodificación.

(En realidad, la enumeración de HARDWARE parece un truco).

  1. ¿La velocidad de decodificación en sí misma / mejor / peor ...?

HARDWARE indicador HARDWARE parece no estar relacionado con la decodificación, por lo que es lo mismo que ARGB_8888 .

  1. ¿Qué pasaría si superamos la memoria de la GPU?

Mi resultado de la prueba en cosas muy malas cuando la memoria se está agotando. El emulador se estrelló horriblemente a veces, y tengo NPE inesperadamente no relacionada en otras ocasiones. No se produjo la excepción OutOfMemoryException, y tampoco había forma de saber cuándo se está agotando la memoria de la GPU, así que no hay manera de prever esto.