2012-01-25 11 views
13

Ho visto in molti esempi che gli sviluppatori chiamano recycle() in bitmap e quindi lo impostano su null. Perché è necessario, il garbage collector non si occupa di rilasciare la bitmap?Android - Gestione bitmap e memoria?

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

risposta

17

Unisciti al club. In qualche modo, ma non del tutto.

Il fatto è che nelle versioni pre-Honeycomb di Android la memoria per bitmap era (è) allocata dalla memoria non gestita, che crea tutti i tipi di problemi. È ancora rilasciato ma dal finalizzatore dell'implementazione dell'oggetto bitmap. Il che significa che occorreranno almeno 2 passaggi di GC per raccoglierlo. Inoltre, se per qualsiasi ragione il finalizzatore non riesce a eseguire - hai ottenuto l'immagine. Un'altra cosa è - è davvero difficile rintracciare - DDMS non lo vede e nemmeno MAT

Per Android 3.0 questo è stato cambiato e le bitmap vengono implementate su array di byte gestiti, ma per i telefoni più vecchi ...

3

bitmap.recycle(); rilascia l'heap nativo che viene utilizzato in bitmap. Impostandolo su null è possibile aiutare il GC a raccogliere rapidamente il tuo riferimento.

+3

@aryaxt: Nota che mentre il finalizzatore eseguirà un 'recycle()' per te, chiamarlo te stesso rilascia prima la memoria, il che rende molto meno probabile che si esaurisca lo spazio heap. – CommonsWare

+1

sì .... ancora una cosa da notare .... è necessario essere sicuri che la bitmap non sia più utilizzata prima di riciclare ... altrimenti si verrebbero a trovare eccezioni quando si tenta di utilizzare una bitmap riciclata. –

+4

Anche a partire da bitmap 3.0 di Android non si usa più l'heap nativo. –

1

Da documenti allo http://developer.android.com/reference/android/graphics/Bitmap.html#recycle%28%29.


Liberare l'oggetto nativo associato a questa bitmap e cancellare il riferimento ai dati del pixel. Questo non libererà i dati dei pixel in modo sincrono; semplicemente gli permette di essere raccolto dalla spazzatura se non ci sono altri riferimenti. La bitmap è contrassegnata come "morta", il che significa che genererà un'eccezione se si chiama getPixels() o setPixels() e non disegnerà nulla. Questa operazione non può essere annullata, quindi dovrebbe essere chiamata solo se sei sicuro che non ci sono ulteriori usi per la bitmap. Questa è una chiamata avanzata e normalmente non deve essere chiamata, poiché il normale processo GC libera questa memoria quando non ci sono più riferimenti a questa bitmap.


Quindi non sembra necessario chiamare. L'unica volta in cui ho sentito la necessità di impostare manualmente un oggetto su null è se si tratta di una variabile statica (o di alcune variabili che non vanno facilmente fuori dallo scope) e si desidera forzarla fuori dalla memoria. Forse se si stanno assegnando rapidamente bitmap in modo rapido, potrebbe essere necessario provare a forzare la garbage collection, ma nella maggior parte dei casi non è probabilmente necessario.

+1

Tutto sembra bene come per la documentazione, ma ci sono stati così tanti casi in cui la bitmap ha causato OOM .... quindi se si affronta questo problema nel codice un modo generale per risolverlo è quello di assicurarsi che impostiamo bitmap per null e chiama il gc dal codice ... (sì, so che questo non è l'optimum e non è garantito a gc) ... ma questa è stata l'ultima risorsa per recuperare un po 'di memoria .... Puoi anche provare utilizzo di SoftReferences per la memorizzazione nella cache bitmap –

+0

Ho caricato centinaia di bitmap in memoria in una sola volta e non ho avuto alcun problema.L'unico modo in cui riesco a vedere questo è un problema sui telefoni moderni è se si perde la memoria delle immagini bitmap o si stanno rapidamente allocando e buttando via le bitmap (molto più di quanto si possa adattare allo schermo in una sola volta). – onit

+0

http://code.google.com/p/android/issues/detail?id=11089 Controlla la risposta dei ragazzi .... –