Verlegen Sie Objekte, die nach Abschluss nicht mit Müll beseitigt wurden

Ich habe festgestellt, dass bei meiner Anwendung Speicherplatz verloren geht. Dies ist in DDMS zu sehen, und es ist mir gelungen, einen OutOfMemoryError zu erhalten.

Ich habe die Quelle des Lecks gefunden. Bei einer der Aktivitäten läuft ein Thread im Hintergrund. Dieser Thread ist in gestopptonDestroy(). Wie in DDMS zu sehen ist, wird die Ausführung beendet.

Wenn nun ein Thread gestartet wird, tritt das Leck auf. Aktivität wird nach der Zerstörung nicht als Müll gesammelt, da der Thread auf sie verweist. Wenn der Thread überhaupt nicht gestartet wird, ist alles in Ordnung.

Hier ist ein einfaches Beispiel, das dies demonstriert:

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    volatile boolean finished = false;
    byte[] memoryEater = new byte[4 * 1024 * 1024];

    Thread thread = new Thread(new Runnable() {

        @Override
        public void run() {
            while (!finished) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            Log.d(getClass().getName(), "Thread finished");
        }
    });

    @Override
    protected void onDestroy() {
        super.onDestroy();
        finished = true;
    }

    public void startActivity(View view) {
        startActivity(new Intent(this, MainActivity.class));
    }

    public void startThread(View view) {
        thread.start();
    }
}

Fügen Sie eine Schaltfläche zum Starten neuer Aktivitäten und eine zum Starten eines Threads hinzu. Neue Aktivität starten. Nach dem Zurückkehren wird der Speicher nur gelöscht, wenn der Thread nicht gestartet wurde.

Was ist die Ursache für dieses Verhalten?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage