廢話不多說直接說流程
- 通過adb dump 內(nèi)存快照
adb shell am dumpheap {進(jìn)程名} {存儲路徑}
例如:
adb shell am dumpheap nova.priv.terminal.player.PlayService /sdcard/1.hprof
- 導(dǎo)出到電腦上
adb pull /sdcard/1.hprof C:\Users\...\1.hprof
- 導(dǎo)出以后我們會得到
1.hprof
文件,但是這個不是mat
工具用到的標(biāo)準(zhǔn)文件敌蜂。我們需要使用sdk自帶的hprof-conv.exe
(platform-tools文件夾下) 工具進(jìn)行轉(zhuǎn)換上岗,轉(zhuǎn)換以后我們就得到了1_mat.hprof
文件
轉(zhuǎn)換mat標(biāo)準(zhǔn)文件
命令:hprof-conv -z src dst
例如:hprof-conv -z 1.hprof 1_mat.hprof
下來我們就需要使用mat進(jìn)行分析了,打開以后如下圖剪侮,我們呢點擊
histogram
mat下載地址:http://www.eclipse.org/mat/downloads.php
-
進(jìn)入Histogram 頁面有我們在紅框位置輸入我們想要找的類需了,然后右鍵選擇
merge shortest paths to Gc roots
然后在選擇exclude all phantom/weak/soft etc.references
選項
-
就得到了如下的引用圖,從圖中我們分析出 loginActivity是被inputMethodManager所引用(這其實是android系統(tǒng)的一個bug),所以我們主要將兩者之間的聯(lián)系給斷開就行,解決方法如下
使用反射的方式將引用的view置為null
InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
try {
//獲得 所有屬性 getField->public 以及父類
Field mCurRootViewField = InputMethodManager.class.getDeclaredField("mCurRootView");
//設(shè)置允許訪問權(quán)限
mCurRootViewField.setAccessible(true);
// 對象
Object mCurRootView = mCurRootViewField.get(im);
if (null != mCurRootView){
Context context = ((View) mCurRootView).getContext();
if (context == this){
//破怪gc 引用鏈
mCurRootViewField.set(im,null);
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}