2015-04-15 11 views
7

Ich habe Speicherlecks untersucht und mit dem Speicheranalyse-Tool überprüft. Also habe ich als Praxis folgenden Code, der eine Aktivität verliert, da die anonyme innere Klasse einen Verweis auf die Aktivität enthält. Hier ist der Code:Memory leak Finalizer-Fehler

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(); 
    } 
} 

ich die Speicher-Analysator Bilder für die oben genannten Lecks hier haben (6 Umdrehungen): 6 Rotations of the activity. enter image description here

Es ist ziemlich klar, dass es 6 laufenden Threads einen impliziten Verweis auf die äußere Halte Aktivität und damit verhindert, dass es Müll gesammelt wird.

Betrachten Sie nun folgenden Code:

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); 
     } 
    } 
    } 
} 

Hier habe ich die Klasse statisch gemacht haben, so dass es keinen Hinweis auf die äußere Aktivität ist und GC kann die Aktivität Objekte frei zugewinnen, ohne durch das Gewinde verhindert wird Klasse.

Hier sind die MAT Screenshots für das gleiche: 6 Rotations again.

enter image description here

Ich habe Verwirrung in Bezug auf den zweiten Satz von Screenshots, wo es 5 Finalizerthread Referenzen. Ich habe darüber gegoogelt und herausgefunden, dass JVM die Objekte zur Referenzwarteschlange hinzufügt, sobald sie im Gange sind. Ich habe erwartet, dass, obwohl dies passieren würde, diese Änderungen in MAT nicht verfügbar sein werden, da ich denke, GC würde nicht viel Zeit brauchen, um diese Referenzen freizugeben. Selbst wenn ich 13 Umdrehungen verwende, ist das Ergebnis das gleiche, mit 12 Finalizer-Referenzen. Ich könnte mich irren, aber ich dachte, dass MAT nur 1 Activity-Objekt anzeigen würde, wie andere GCed haben müssen. Jede Hilfe in Bezug auf die Finalisierungsreferenzwarteschlange und der Prozess, der während der Speicherbereinigung fortgesetzt wird, werden geschätzt. Vielen Dank.

+0

Haben Sie versucht, einen Müll zu sammeln? –

+0

Nun, nein, ich habe es nicht versucht. Für den zweiten Fall denke ich, dass GC automatisch Speicher zurückgewinnen würde, da es nichts daran hindert, dies zu tun. Das Einfügen von Objekten in die Finalizer-Warteschlange zeigt an, dass der Speicher zwar bereit ist, zurückgewonnen zu werden, aber meine Verwirrung ist, dass er nicht in MAT reflektiert wird. –

Antwort

3

enter image description here

Select Finalizer Überblick. Es gibt Informationen über die Anzahl der Objekte, die darauf warten, dass der Finalizer ausgeführt wird, und weitere Informationen zum Finalizer-Thread.