Magren

Magren

Idealist & Garbage maker 🛸
twitter
jike

Androidのメモリリークとオーバーフローについて話しましょう。

大学で 1 年以上 Android を学んできましたが、一部の要件はすでに完了できるようになりましたが、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 のメモリオーバーフロー#

メモリオーバーフローとは、アプリがシステムに最大閾値を超えるメモリ要求を行い、システムが余分なスペースを割り当てないためにメモリがオーバーフローすることを指します。

  • 典型的な例は、多数の大きな画像をロードすることでメモリを消費し尽くすことです。画像を適切に品質圧縮したり、サイズを圧縮したりすることができます。
  • 特定の画面にメモリリークが存在し、繰り返しにその画面に入ると、新しいオブジェクトが作成され続けますが、回収されないため、最終的にメモリが枯渇し、メモリオーバーフローが発生します。
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。