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()方法
好,完畢