Enhebre objetos que no sean basura recolectados después de ser terminado
Noté que mi aplicación está perdiendo memoria. Esto se puede ver en DDMS, y logré obtener un OutOfMemoryError.
Encontré la fuente de la fuga. Una de las actividades tiene un hilo que se ejecuta en segundo plano. Este hilo se detiene enonDestroy()
. Termina de ejecutarse, como se puede ver en DDMS.
Ahora, si se inicia el subproceso, se produce la fuga, la actividad no se recolecta como basura después de ser destruida, porque el subproceso hace referencia a ella. Si el hilo no se inicia en absoluto, todo está bien.
Aquí hay un ejemplo simple que demuestra esto:
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();
}
}
Agregue un botón para iniciar una nueva actividad y otro para iniciar un hilo. Iniciar nueva actividad. Después de volver, la memoria se limpiará solo si el hilo no se ha iniciado.
¿Cuál es la causa de este comportamiento?