Android: ¿Cómo funciona Bitmap recycle ()?

Digamos que he cargado una imagen en un objeto de bitmap como

Bitmap myBitmap = BitmapFactory.decodeFile(myFile); 

Ahora, ¿qué pasará si cargo otro bitmap como

 myBitmap = BitmapFactory.decodeFile(myFile2); 

¿Qué pasa con el primer myBitmap? ¿Obtiene Garbage Collected o tengo que recolectarlo manualmente antes de cargar otro bitmap, por ej. myBitmap.recycle() ?

Además, ¿hay una mejor manera de cargar imágenes grandes y mostrarlas una tras otra mientras se recicla en el camino?

El primer bitmap no recibe GC cuando decodifica el segundo. GC lo hará más tarde cuando lo decida. Si desea liberar memoria lo antes posible, debe llamar a reciclar () justo antes de decodificar el segundo bitmap.

Si desea cargar una imagen realmente grande, debe volver a muestrearla. Aquí hay un ejemplo Extraño problema de memoria al cargar una imagen en un objeto Bitmap .

Deberá llamar a myBitmap.recycle () antes de cargar la siguiente imagen.

Dependiendo de la fuente de su myFile (por ejemplo, si no tiene control sobre el tamaño original), al cargar una imagen en lugar de simplemente volver a muestrear un número arbitrario, debe escalar la imagen al tamaño de visualización.

 if (myBitmap != null) { myBitmap.recycle(); myBitmap = null; } Bitmap original = BitmapFactory.decodeFile(myFile); myBitmap = Bitmap.createScaledBitmap(original, displayWidth, displayHeight, true); if (original != myBitmap) original.recycle(); original = null; 

Guardo en caché el displayWidth y displayHeight en una estática que inicié al inicio de mi actividad.

 Display display = getWindowManager().getDefaultDisplay(); displayWidth = display.getWidth(); displayHeight = display.getHeight(); 

Creo que el problema es el siguiente: en las versiones anteriores a Honeycomb de Android, los datos de bitmap en bruto no se almacenan en la memoria de la máquina virtual, sino en la memoria nativa. Esta memoria nativa se libera cuando el objeto de Bitmap java correspondiente es GC’d.

Sin embargo , cuando te quedas sin memoria nativa, el dalvik GC no se activa, por lo que es posible que tu aplicación utilice muy poca memoria java, por lo que el dalvik GC nunca se invoca, aunque utiliza toneladas de memoria nativa para mapas de bits. que eventualmente causa un error OOM.

Al menos esa es mi suposición. Afortunadamente en Honeycomb y más tarde, todos los datos de mapas de bits se almacenan en la máquina virtual, por lo que no debería tener que usar recycle() en absoluto. Pero para los millones de usuarios de 2.3 (la fragmentación sacude el puño ), debe usar recycle() siempre que sea posible (una molestia masiva). O, como alternativa, puede invocar el GC en su lugar.

Una vez que el bitmap había sido cargado en la memoria, de hecho fue hecho por dos partes de datos. La primera parte incluye información sobre el bitmap, otra parte incluye información sobre los píxeles del bitmap (está ordenada por una matriz de bytes). La primera parte existe en la memoria utilizada de Java, la segunda parte exisita en la memoria utilizada de C ++. Puede usar la memoria de los demás directamente. Bitmap.recycle () se usa para liberar la memoria de C ++. Si solo hace eso, el GC recogerá la parte de java y siempre se usará la memoria de C.

Timmmm tenía razón.

de acuerdo con: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

Además, antes de Android 3.0 (API nivel 11), los datos de respaldo de un bitmap se almacenaron en la memoria nativa, que no se publica de manera predecible, lo que puede causar que una aplicación exceda brevemente sus límites de memoria y falle.