2015-04-15 13 views
7

Ho studiato le perdite di memoria e utilizzo lo strumento dell'analizzatore di memoria per controllarle. Quindi, come pratica, ho il seguente codice che perde un'attività mentre la classe interiore anonima contiene un riferimento all'attività. Ecco il codice:Errore di finalizzatore della perdita di memoria

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    exampleOne(); 
    } 

    private void exampleOne() { 
    new Thread() { 
     @Override 
     public void run() { 
     while (true) { 
      SystemClock.sleep(1000); 
     } 
     } 
    }.start(); 
    } 
} 

Ho le immagini analizzatore memoria per le perdite sopra qui (6 rotazioni): 6 Rotations of the activity. enter image description here

È chiaro che ci sono 6 fili conduttori che tengono un riferimento implicito esterno attività, impedendo in tal modo che vengano raccolti rifiuti.

Ora, considero seguente codice:

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    exampleTwo(); 
    } 

    private void exampleTwo() { 
    new MyThread().start(); 
    } 

    private static class MyThread extends Thread { 
    @Override 
    public void run() { 
     while (true) { 
     SystemClock.sleep(1000); 
     } 
    } 
    } 
} 

Qui, ho fatto la classe statica, in modo che non c'è alcun riferimento all'attività esterna e GC possono liberamente recuperare gli oggetti di attività senza essere impedito dal filo classe.

Ecco gli screenshot MAT per lo stesso: 6 Rotations again.

enter image description here

devo confusione per quanto riguarda la seconda serie di screenshot, dove ci sono 5 i riferimenti Finalizer. L'ho cercato su google e ho scoperto che JVM aggiunge gli oggetti alla coda di riferimento una volta che stanno per diventare GCed. Mi aspettavo che, sebbene ciò accadesse, tali modifiche non saranno disponibili in MAT poiché non credo che GC impiegherebbe molto tempo per liberare tali riferimenti. Anche se uso 13 rotazioni, il risultato è lo stesso, con 12 riferimenti di finalizzatore. Potrei sbagliarmi, ma ho pensato che MAT avrebbe mostrato solo 1 oggetto Activity come gli altri devono essere stati GCed. Qualsiasi aiuto per quanto riguarda la coda di riferimento di finalizzazione e il processo che si verifica durante la garbage collection sarebbe apprezzato. Grazie.

+0

Hai provato a forzare un cestino della spazzatura? –

+0

Beh, no non ho provato a forzare. Per il secondo caso, penso che GC riacquisirà automaticamente la memoria poiché non c'è nulla che gli impedisca di farlo. Mettere gli oggetti nella coda del finalizzatore indica che effettivamente la memoria è pronta per essere recuperata, ma la mia confusione è che il motivo per cui non si riflette in MAT. –

risposta

3

enter image description here

Panoramica selezionare Finalizer. Fornisce informazioni sul numero di oggetti in attesa dell'esecuzione del finalizzatore e altre informazioni correlate del thread del finalizzatore.