2012-01-25 21 views
13

He visto en muchas muestras que los desarrolladores llaman a recycle() en mapa de bits y luego lo configuran en null. ¿Por qué es esto necesario, el recolector de basura no se ocupa de liberar el mapa de bits?Android - ¿Administración de mapa de bits y memoria?

Bitmap bitmap = BitmapFactory.decodeStream(inputStream); 
bitmap.recycle(); 
bitmap = null; 

Respuesta

17

Únete al club. Es algo que hace pero no del todo.

Lo que pasa es que en las versiones anteriores a Honeycomb de Android, la memoria para mapas de bits se asignaba desde la memoria no administrada, lo que crea todo tipo de problemas. Todavía se lanza, pero desde el finalizador de la implementación del objeto de mapa de bits. Lo que significa que tomará al menos 2 pases de GC para recogerlo. Además, si por algún motivo el finalizador no se ejecuta, usted tiene la imagen. Otra cosa es - es realmente difícil de rastrear - DDMS no lo ve y tampoco lo hace MAT

Para Android 3.0 esto ha sido cambiado y mapas de bits se ejecutará en las matrices de bytes administrados, pero para los teléfonos antiguos ...

3

bitmap.recycle(); libera el montón nativo que se usa en los mapas de bits. Y establecerlo en nulo es ayudar al GC a recopilar rápidamente tu referencia.

+3

@aryaxt: tenga en cuenta que si bien el finalizador hará un 'recycle()' para usted, al llamarlo usted mismo liberará la memoria antes, por lo que es mucho menos probable que se quede sin espacio en el montón. – CommonsWare

+1

sí .... una cosa más a tener en cuenta ... debe asegurarse de que el mapa de bits ya no se usa antes de reciclar ... de lo contrario, se encontrarían con excepciones al intentar usar un mapa de bits reciclado. –

+4

También a partir de mapas de bits de Android 3.0 ya no usas el montón nativo. –

1

De docs en http://developer.android.com/reference/android/graphics/Bitmap.html#recycle%28%29.


Libere el objeto nativo asociado a este mapa de bits y borre la referencia a los datos de píxeles. Esto no liberará los datos de píxel de forma síncrona; simplemente permite que se recolecte basura si no hay otras referencias. El mapa de bits está marcado como "muerto", lo que significa que emitirá una excepción si se llama a getPixels() o setPixels(), y no dibujará nada. Esta operación no se puede revertir, por lo que solo debe invocarse si está seguro de que no hay más usos para el mapa de bits. Esta es una llamada avanzada, y normalmente no necesita ser llamada, ya que el proceso GC normal liberará esta memoria cuando ya no haya más referencias a este mapa de bits.


Parece que no es necesario llamar. La única vez que escuché la necesidad de establecer manualmente un objeto como nulo es si es una variable estática (o alguna variable que no saldrá fácilmente del alcance) y desea forzarla a que quede fuera de la memoria. Tal vez si continuamente asigna mapas de bits rápidamente, puede ser necesario tratar de forzar la recolección de basura, pero en la mayoría de los casos probablemente no sea necesario.

+1

Todo parece estar bien según la documentación, pero ha habido tantos casos en que el mapa de bits ha causado OOM ... así que si enfrenta este problema en su código, una forma general de solucionarlo es asegurarse de que establezcamos el mapa de bits en null y llamar al gc desde el código ... (sí, sé que esto no es lo óptimo y no está garantizado a gc) ... pero este ha sido el último recurso para recuperar algo de memoria ... También puedes probar Uso de SoftReferences para el almacenamiento en memoria caché de mapa de bits –

+0

He cargado cientos de mapas de bits en la memoria a la vez y no he tenido ningún problema.La única forma en que puedo ver que esto es un problema en los teléfonos modernos es si tiene pérdida de memoria en sus bitmaps o está asignando y tirando rápidamente bitmaps (mucho más de lo que puede caber en su pantalla de una vez). – onit

+0

http://code.google.com/p/android/issues/detail?id=11089 Compruebe la respuesta de chicos romanos .... –

Cuestiones relacionadas