私のアプリでメモリリークの捜索で私は理解できない振る舞いを追いかけました。私は大きなメモリブロックを割り当てますが、onDestroyの参照を明示的にnullにしない限り、OOMの結果としてガベージコレクションされません。大きなメモリチャンクはガベージコレクトされていません
この例では、2つのほぼ同じアクティビティがあり、お互いに切り替わります。両方とも1つのボタンがあります。 MainActivityボタンを押すとOOMActivityが開始され、finish()を呼び出してOOMActivityが戻ります。ボタンを数回押すと、AndroidはOOMExceptionをスローします。
OOMActivityにonDestroyを追加してメモリチャンクへの参照を明示的にnullにすると、メモリ内のメモリが正しく解放されていることがログに記録されます。
ヌルなしでメモリが自動的に解放されないのはなぜですか?
MainActivity:
package com.example.oom;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
private int buttonId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.gc();
Button OOMButton = new Button(this);
OOMButton.setText("OOM");
buttonId = OOMButton.getId();
setContentView(OOMButton);
OOMButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == buttonId) {
Intent leakIntent = new Intent(this, OOMActivity.class);
startActivity(leakIntent);
}
}
}
OOMActivity:アクティビティ破壊がこのケースでのAndroid(あなたはクラスがOSを意味するものではありません表示されていないという理由だけで、クラスの破壊を意味するものではありません
public class OOMActivity extends Activity implements OnClickListener {
private static final int WASTE_SIZE = 20000000;
private byte[] waste;
private int buttonId;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button BackButton = new Button(this);
BackButton.setText("Back");
buttonId = BackButton.getId();
setContentView(BackButton);
BackButton.setOnClickListener(this);
waste = new byte[WASTE_SIZE];
}
public void onClick(View view) {
if (view.getId() == buttonId) {
finish();
}
}
}
素晴らしい例です。 – WarrenFaith
このチャットをお読みください。我々は[ここでそれについて議論しました](http://chat.stackoverflow.com/transcript/message/10084186#10084186) – Reno
これは、ハニカム前のデバイスでこれをテストしている可能性があります。ポストハニカムのガベージコレクタは、 "無駄な"オブジェクトを解放するほど攻撃的です。 4.1.2,4.2.2,2.3.5,2.3.7でテスト済み。 "waste = new byte [WASTE_SIZE]"の前にSystem.gc()を呼び出すと、ハニカム前のデバイスの問題を回避できます。 – pellucide