內存泄漏分析檢測

檢測工具

  • AndroidStudio3.0以上
  • Memory analyzer或者eclipse MAT插件

1.準備工作:

首先我們模擬內存泄漏,如下代碼:
ToastUtils.java

public class ToastUtils {
    private static final ToastUtils ourInstance = new ToastUtils();
    private static Context mContext;

    public static ToastUtils getInstance(Context context) {
        mContext =context;
        return ourInstance;
    }

    private ToastUtils() {
    }

    public void showToast(String msg){
        Toast.makeText(mContext,msg,Toast.LENGTH_SHORT).show();
    }

}

Main2Activity

public class Main2Activity extends AppCompatActivity {

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        ToastUtils.getInstance(this).showToast("hahahhaha");

        handler.sendEmptyMessageDelayed(1,6000);
    }
}

2.開始檢測

2.1以Android Profiler運行應用程序,點擊如下按鈕

Android Profiler

2.2選擇MEMORY,點擊如下按鈕

MEMORY

2.3開始進行測試,隨便點點我們的應用然后點擊下圖1按鈕請求gc,再點擊2獲取一份內存快照,如下:

獲取內存快照

2.4分析生成的文件,生成的文件如下圖:

內存快照
  • Alloc Cout 對象數
  • Shallow Size 對象占用內存大小
  • Retained Set 對象引用組占用的內存

注:如果Alloc Cout 數量不是1的話,可能就發生了內存泄漏

2.4點擊保存到本地,文件名為1.hprof

保存到本地

2.5使用hprof-conv命令轉成標準的mat文件

命令如下:

hprof-conv -z /Users/cool/me/1.hprof /Users/cool/me/1_mat.hprof

如果找不到hprof-conv命令,請配置一下環境變量,hprof-con為/SDK/platform-tools/下的工具
將1_mat.hprof拖到 Memory analyzer中,或者已安裝mat插件的eclipse中
如下:


mat

點擊紅框中的按鈕,再根據泄漏的類名Main2Activity來篩選,


image.png

回車,得到下面結果

image.png

選中要排查的類,排除軟弱虛引用


image.png

將得到結果全部展開,如下:

image.png

分析此圖,我們看到有3個泄漏點,因為內存泄漏是自己模擬的,所以我們很快就能定位到問題,這里假裝是真實開發的項目,我們一個一個分析:

  • 第一個泄漏點:沿著Main2Activity一直往上追溯,會發現GCRoot為 com.cool.skinresource.ToastUtils,這里的代碼寫的有問題,打開后發現單例中靜態引用Activity實例導致gc無法回收
  • 第二個泄漏點:仔細看就知道handler機制導致的內存泄漏,非靜態內部類持有外部類Activity的引用導致的
    *第三個泄漏點:Toast的內部類mNextView,mView持有了Activity的引用,這里是因為靜態的Context才導致的,如果需要解決此泄漏,需要通過反射將mNextView,mView置為null,將引用鏈打破即刻

將問題解決后再重復此步驟檢測,直至沒有內存泄漏

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。