Android內存泄漏檢查利器——LeakCanary

內存泄漏也稱作“存儲滲漏”,用動態存儲分配函數動態開闢的空間,在使用完畢後未釋放,結果導致一直佔據該內存單元,直到程序退出,如果在程序退出前達到了系統所分配的最大內存限度時,則會觸發OOM導致程序崩潰。相信大多開發者對於內存泄漏並不陌生,但是如何去發現內存泄漏、定位內存泄漏以及處理內存泄漏可能就有些生疏了。本篇將介紹如何使用Android內存泄漏檢查利器——LeakCanary去發現內存泄漏以及定位到內存泄漏。而在處理內存泄漏上我們需要根據具體情況採取具體的措施。

LeakCanary

LeakCanary是一個Android和Java的內存泄露檢測庫,可以大幅度減少了開發中遇到的OOM問題

配置LeakCanary

LeakCanary的配置很簡單,首先在app中的build.gradle裏的dependencies接點下引用

com.squareup.leakcanary:leakcanary-android:1.4-beta2

dependencies {
    compile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
}

接着我們需要自己創建Application,並在onCreate方法中初始化它。

public class MainApplication extends Application{

    @Override
    public void onCreate() {
        super.onCreate();
        RefWatcher refWatcher = LeakCanary.install(this);
    }
}

最後在AndroidManifest配置一下我們創建的Application就行了。

<application
        android:allowBackup="true"
        android:name=".MainApplication"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ... ...
</application>

編譯運行到手機上後的情況如下圖所示就算是配置成功了。

這裏寫圖片描述

這裏多出了一個應用——Leaks。現在打開到裏面看除了導航欄指明此Leak屬於哪個應用的之外,什麼東西都沒有。這個可以先不管,我們寫一段會發生內存泄漏的代碼來看看會是什麼情況。

這裏我們採用最典型的單例引起的Context內存泄漏來做示例。

public class MyInstance {
    private Context context;
    private static MyInstance mInstance;

    public static MyInstance getInstance(Context context) {
        if (mInstance == null) {
            synchronized (MyInstance.class) {
                if (mInstance == null)
                    mInstance = new MyInstance(context);
            }
        }
        return mInstance;
    }

    private MyInstance(Context context) {
        this.context = context;
    }

}

接着我們新建一個Activity,在onCreate中傳入自身的context來初始化MyInstance。

public class TestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        MyInstance.getInstance(this);

    }
}

然後在MainActivity中寫個按鈕點擊事件跳轉到TestActivity中,再在TestActivity回退到MainActivity。

回退到MainActivity中等待一小會後我們可以看到Leaks發出了通知消息,說明已經檢測到出現了內存泄漏的問題。點開通知我們可以看到如下界面:

這裏寫圖片描述

可以發現是在TestActivity中發生的內存泄漏,原因是MyInstancem的mInstance引用的context爲TestAcitivty。現在如果我們打開Leaks,可以發現它已經爲我們記錄了一條內存泄漏的信息。

因此,我們只需將創建MyInstancem的傳入值改成生命週期最長的ApplicationContext後就能解決這個問題了。

在開發中我們在一開始就應該對程序進行內存泄漏檢查,以便我們及時發現內存泄漏的問題並更加容易定位到問題代碼,採取相應的解決措施。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章