1. 程式人生 > >Android 記憶體洩漏之LeakCanary

Android 記憶體洩漏之LeakCanary

導言:
記憶體管理是android開發效能中重要的一環,而leakCanary是Square開源框架,是一個Android記憶體洩露檢測庫,是個優秀的
記憶體洩露檢測工具,通過它大大降低oom的出現,提高app的質量

釋義:
記憶體洩漏:物件在有限生命週期內還持有引用,沒有被回收,並最終消耗完記憶體

引入:
1:build.gradle中

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.2'

2:更改Application

public class LeakApplication extends Application {
    private static RefWatcher refWatcher;
    @Override
    public void onCreate() {
        super.onCreate();
        refWatcher= LeakCanary.install(this);
    }
}

3:在需要的地方使用,比如activity和fragment的onDestroy中,監控指定的物件

//activity和fragment中
@Override protected void onDestroy() { super.onDestroy(); LeakApplication.getRefWatcher(this).watch(this); } //指定的物件 LeakApplication.getRefWatcher(this).watch(someObjneedWatch);

方案:

1:使用單例造成的記憶體洩漏
原因:單例的靜態特性使得單例的生命週期和應用的生命週期一樣長,導致這個物件將不能被正常回收
方案:通過context.getApplicationContext()解決

這裡寫圖片描述

2:Handler造成的記憶體洩漏
原因:Message持有mHandler例項的引用,mHandler又持有Activity的引用,導致該Activity的記憶體資源無法回收
方案:只需在onDestroy()函式中呼叫mHandler.removeCallbacksAndMessages(null)和mHandler=null
這裡寫圖片描述

3:AsyncTask執行緒造成的記憶體洩漏
原因:在處理一個比較耗時的操作時,可能還沒處理結束MainActivity就執行了退出操作
方案:在Activity的onDestory()方法中取消相應的任務AsyncTask.cancel()和asyncTask = null方法
這裡寫圖片描述

4:非靜態內部類建立靜態例項造成的記憶體洩漏
原因:在MainActivity關閉的時候,內部類靜態例項依然持有對MainActivity的引用
方案:將內部類改成靜態內部類,不再持有對MainActivity的引用即可
這裡寫圖片描述

5:WebView引起的記憶體洩漏
原因:WebView解析網頁時會申請Native堆記憶體用於儲存頁面元素,當頁面較複雜時會有很大的記憶體佔用,當然還要圖片
方案:使用了WebView的Activity(或者Service)放在單獨的程序裡和主動Kill掉程序


//第一步,放在單獨的程序裡
<activity
   android:name=".MainActivity5"
   android:process="com.aile.webview"/>
//第二步,置空和kill
 if (mWebView != null) {
            mWebView.pauseTimers();
            mWebView.removeAllViews();
            mWebView.destroy();
            mWebView = null;
        }
android.os.Process.killProcess(android.os.Process.myPid());

這裡寫圖片描述

6:自定義view造成的記憶體洩漏
原因:view中有執行緒或者動畫 要及時停止
方案:在onDestroy方法中將view=null

7:資源未關閉造成的記憶體洩漏
原因:BroadcastReceiver,ContentObserver,File,Cursor,Bitmap,動畫等資源的使用,應該在Activity銷燬時及時登出
方案:在onDestory中cancel()或close()方法

好,完畢