大学で Android を学んでから 1 年以上経ちましたが、一部の要件を満たすことができるようになりました。しかし、Android の低レベルの知識やいくつかの概念については、あまり理解していないと思います。この長い休暇の機会を利用して、しっかりと理解することを計画しています。
Android のメモリリーク#
メモリリークとは、アクセス不可能な変数の参照を保持することにより、ガベージコレクタがメモリを回収できなくなることを指します。
つまり:
Java では、いくつかのオブジェクトのライフサイクルは限られており、特定のロジックが完了すると回収されるはずですが、オブジェクトのライフサイクルが終了するはずの時に、そのオブジェクトがまだ他のオブジェクトによって参照されている場合、メモリリークが発生します。
具体的な例:
public class LeakAct extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aty_leak);
test();
}
public void test() {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}z
}
}).start();
}
}
test は非静的な内部クラスであり、私たちが finish を呼び出したとき、このインスタンスは実際には破棄されず、GC メカニズムもこのインスタンスをガベージコレクションしません。なぜなら、*** 匿名内部クラスと非静的な内部クラスは外部クラスへの強い参照を保持しているからです。*** つまり、test は外部の activity への強い参照を保持しており、スレッド内の while (true) は無限ループであり、スレッドは停止しないため、外部の activity への強い参照も消えません。これにより、メモリリークが発生します。
解決策
1. 内部クラスを静的な内部クラスに変更する。
2.Activity のプロパティに強い参照がある場合は、その参照方法を弱い参照に変更する。
3. ビジネス上許容される場合、Activity が onDestory を実行するときにこれらの時間のかかるタスクを終了する。
Android のメモリオーバーフロー#
メモリオーバーフローは、アプリがシステムに最大閾値を超えるメモリリクエストを要求し、システムが余分なスペースを割り当てないため、メモリがオーバーフローすることを指します。
- 典型的な例は、多くの大きな画像を読み込むことでメモリを消費し、適切な品質圧縮やサイズ圧縮を行うことができます。
- 特定の画面にメモリリークが存在する場合、その画面に繰り返し入ると、新しいオブジェクトが作成され続けますが、回収されないため、最終的にメモリが枯渇し、メモリオーバーフローが発生します。