アプリケーションでメモリ リークが発生していることに気付きました。これは DDMS で確認でき、OutOfMemoryError を取得することができました。
漏れの元を見つけました。アクティビティの 1 つに、バックグラウンドで実行されているスレッドがあります。このスレッドは で停止していonDestroy()
ます。DDMS で確認できるように、実行が終了します。
現在、スレッドが開始されると、リークが発生します。アクティビティは、スレッドによって参照されるため、破棄された後にガベージ コレクションされません。スレッドがまったく開始されていない場合は、すべて問題ありません。
これを示す簡単な例を次に示します。
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();
}
}
新しいアクティビティを開始するためのボタンを 1 つ、スレッドを開始するためのボタンを 1 つ追加します。新しい活動を開始します。戻った後、スレッドが開始されていない場合にのみメモリが消去されます。
この動作の原因は何ですか?