一篇文章教會你---怎樣理解Android內(nèi)存泄漏以及如何分析

首先我們先談?wù)刯ava對象回收條件是什么?

當沒有任何引用指向該對象的時候。
(存在兩種情況:1.該對象的最后一個引用指向了另一個對象或null。 2.該對象的最后一個引用的作用域結(jié)束。)

內(nèi)存泄漏是什么?

內(nèi)存泄漏通俗來講就是長生命周期對象強引用了短生命周期對象,在短生命周期對象想回收時,強生命周期還是不對其解除引用。這時候短生命周期對象就不會被回收,但我們的想法是以后不會用這個短生命周期對象了,這時候該對象就是泄漏的垃圾對象了。當這些對象泄漏的多了,就會占用大量內(nèi)存,最終結(jié)果也就造成oom了。

下面我就用個簡單的例子,來看看是不是這樣的

public class Main2Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Log.i("----------", "onCreate: activity_main2");
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}
1.png
2.png
上面兩張圖我們很容易看出,我打開并退出了5次Main2Activity,然后用內(nèi)存分析工具強制gc后Main2Activity實例數(shù)依然是5個,此時就是內(nèi)存泄漏了。而內(nèi)存泄漏的原因就是Thread對象持有了Runnable對象(和他持有Runnable關(guān)系不大),Runnable對象中的run方法又間接持有了Main2Activity(這才是主要原因),然而這個Runnable對象中run方法短期又執(zhí)行不完,結(jié)果就造成Runnable對象不會回收,Main2Activity也無法回收。

問題:此時Thread對象有沒有回收?

答案:沒有回收。
看下源碼就知道原因了:

public class Thread implements Runnable {

    private Runnable target;

    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
}

我們可以看出Thread對象中也實現(xiàn)了Runnable接口,然后thread中run方法中調(diào)用了target.run();而這個target就是我們剛剛在Main2Activity中實現(xiàn)的Runnable對象。當我們開啟一個線程之后,最終它會在那個線程中運行這個run方法,然而target.run執(zhí)行結(jié)束前,thread的run方法肯定也結(jié)束不了了,就造成thread也無法回收(從另一個角度理解:thread中的run方法肯定也是持有thread對象的引用,所以這些方法執(zhí)行完畢前這些被方法引用的對象也自然無法回收了)

最后再推薦一個很多人都知道的一個Android內(nèi)存泄漏檢查框架,leakcanary,我們也可以用他來檢查內(nèi)存泄漏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容