2012-09-15 14 views
7

Lavoro con diversi drawable di grandi dimensioni e non so come gestire le perdite di memoria. Ho rintracciato la dimensione heap della mia applicazione e non si ferma a crescere (come la memoria allocata).Perdita di memoria dei Drawables Android

È in particolare il tipo "byte array (byte [])" che cresce e non diminuisce mai. (nella vista heap di DDMS su Eclipse)

La mia applicazione è composta da un'attività che utilizza i frammenti. Questi frammenti mostrano diverse immagini di grandi dimensioni. Ho provato a impostare il callback drawable su null, impostare drawable su null, svuotare la cache volatile (che impedisce alla mia app di fare troppi I/O disco) quando faccio il popback di un frammento ma l'heap non diminuisce mai.

Infatti, ogni volta che chiamo: Drawable.createFromResourceStream (context.getResources(), valore, nuovo FileInputStream (f), f.getName(), opts); l'heap cresce. Come posso liberare la memoria?

Grazie!

risposta

6

Una perdita di memoria si verifica quando Java trova oggetti nella memoria a cui fa riferimento il codice che impedisce a Garbage Collector di liberare questa memoria. Una causa comune in Android è il riferimento al contesto dell'attività piuttosto che al contesto dell'applicazione. Assicurati che il tuo contesto fa riferimento l'applicazione (ad esempio utilizzare getApplicationContext piuttosto che utilizzare this. Controllare questo video per la spiegazione sulle perdite di memoria e controllare anche questo question.

+0

Ho riferimento il contesto dell'applicazione e non il contesto di attività, si ritiene che il problema è che i miei frammenti non sono mai distrutte e perdite? – abecker

+0

Forse, controlla il video nella mia risposta su come usare lo strumento di analisi della memoria SDK (MAT) per trovare gli oggetti che perdono –

+1

Hey! Ho risolto il mio problema! In effetti, i miei frammenti erano tenuti in memoria ed era la mia cache volatile statica a tenerlo. Non so davvero perché ha questo comportamento. Ho istanziato un DrawableManager, quando creo un frammento, che ha diversi metodi per recuperare i Drawable dal disco o dal networking. Quando ne consegna uno ai miei punti di vista, lo manteneva in una HashMap statica (per riutilizzare questa cache nei miei altri frammenti). Ho solo reso la mia HashMap statica (non posso riutilizzare la cache volatile tra i frammenti). Non so perché il mio frammento sia stato tenuto in memoria. – abecker

2

la questione sembra risolta, ma un post di Romain Guy sembra rilevante per maggiori informazioni :. Avoiding Memory Leaks

a quanto pare, se (ad esempio) di impostare una drawable come immagine di sfondo per una vista testo utilizzando setBackgroundDrawable * (allegando così la drawable alla vista), quindi modificare l'orientamento (distruggendo l'attività e ridisegnare la UI) il drawable avrà ancora accesso alla vecchia attività (dopo la distruzione della vecchia attività), creando così una perdita di memoria.

* (come nota a margine - setBackgroundDrawable è stato deprecated since API level 16)

+0

... eppure setBackgroundDrawable viene ancora chiamato internamente da setBackground anche in API 24. :) –