Objetos de encadeamento não são lixo coletado após o término
Percebi que meu aplicativo está vazando memória. Isso pode ser visto no DDMS e consegui obter um OutOfMemoryError.
Eu encontrei a fonte do vazamento. Uma das atividades tem um encadeamento em execução em segundo plano. Este thread está parado emonDestroy()
. Ele termina a execução, como pode ser visto no DDMS.
Agora, se o encadeamento for iniciado, o vazamento ocorrerá, a Atividade não será coletada após ser destruída, porque é referenciada pelo encadeamento. Se o thread não for iniciado, tudo está bem.
Aqui está um exemplo simples demonstrando isso:
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();
}
}
Adicione um botão para iniciar uma nova atividade e um para iniciar um segmento. Inicie uma nova atividade. Depois de voltar, a memória será limpa apenas se o encadeamento não tiver sido iniciado.
Qual é a causa desse comportamento?