利用leakCanary自動抓取內(nèi)存泄露堆棧

需求痛點(diǎn):leakCanary雖然很傻瓜了,但是必須要手動點(diǎn)開通知才能看到泄露信息袭厂,如果自動測試就無法保存現(xiàn)場仁堪。自動跑monkey和mtbf時(shí),出現(xiàn)了內(nèi)存泄露打却,但是沒有抓取到相關(guān)的信息杉适,無法分析,明知道有泄露但是無法找到原因柳击,非常痛苦猿推。

適用范圍:僅適用于java層的內(nèi)存泄露,基于leakCanary源碼實(shí)現(xiàn)捌肴。

編譯配置:

在gradle中編譯蹬叭,可參考源碼中的引用方式,在build.gradle中添加如下配置状知。

dependencies{

debugCompile project(':leakcanary-android')

releaseCompile project(':leakcanary-android-no-op');

}

在源碼中編譯秽五,Android.mk文件中配置如下。并將相應(yīng)jar包拷貝到對應(yīng)目錄下(此處為libs)饥悴,并保證名字相同坦喘。jar包獲取地址:auto-leak-detect.rar

LOCAL_AAPT_FLAGS := --auto-add-overlay

LOCAL_AAPT_FLAGS += --extra-packages com.squareup.leakcanary

LOCAL_STATIC_JAVA_LIBRARIES += dpt-haha-2.0.3.jar

LOCAL_STATIC_JAVA_AAR_LIBRARIES := \

dpt-leakcanary-watcher-1.4-beta2 \

dpt-leakcanary-analyzer-1.4-beta2 \

dpt-leakcanary-android-1.4-beta2 \

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \

dpt-haha-2.0.3:libs/haha-2.0.3.jar \

dpt-leakcanary-analyzer-1.4-beta2:libs/leakcanary-analyzer-1.4-beta2.aar \

dpt-leakcanary-watcher-1.4-beta2:libs/leakcanary-watcher-1.4-beta2.aar \

dpt-leakcanary-android-1.4-beta2:libs/leakcanary-android-1.4-beta2.aar \

源碼編譯方式可參考郵件的提交:http://diana.devops.letv.com/#/c/257105/

如果需要加入混淆,請?jiān)诨煜渲梦募屑尤肴缦屡渲梦魃瑁@個(gè)配置在源碼的混淆文件中就有起宽,拷貝過來列在下面。

-dontwarn com.squareup.haha.guava.**

-dontwarn com.squareup.haha.perflib.**

-dontwarn com.squareup.haha.trove.**

-dontwarn com.squareup.leakcanary.**

-keep class com.squareup.haha.** { *; }

-keep class com.squareup.leakcanary.** { *; }

# Marshmallow removed Notification.setLatestEventInfo()

-dontwarn android.app.Notification

使用方式:

在自定義的Application中調(diào)用LeakCanary.install(this);

獲取自動保存的文件并分析:

在原來打開通知欄時(shí)济榨,我們會看到一個(gè)如下圖所示的列表坯沪,列表中每項(xiàng)都代表一個(gè)泄露,打開其中一項(xiàng)后擒滑,會有一個(gè)泄露的堆棧信息腐晾。

以源碼中的samle apk為例叉弦,產(chǎn)生的文件保存在/sdcard/Download/leakcanary-com.example.leakcanary中,此處com.example.leakcanary根據(jù)被檢查的宿主apk命名藻糖。打開文件夾淹冰,如下面左圖所示。

其中后綴名為.leakinfo的文件巨柒,就是我們自動加上的文件樱拴,打開其中一個(gè)查看,與上面的右圖中的堆棧信息一一對應(yīng)洋满【牵看看has leaked:后面的堆棧信息,如上面右圖中的堆棧信息是一樣的:root是一個(gè)Thread牺勾,references代表引用了一個(gè)對象正罢,這里是com.example.leakcanary.MainActivity$2.this$0,這個(gè)可能有多個(gè)驻民。最后leaks com.example.leakcanary.MainActivity instance代表導(dǎo)致了一個(gè)MainActivity的泄露翻具。當(dāng)然,文件中有比上圖中更豐富的信息,有興趣的同學(xué)可以再研究。

原理分析:

在源碼中弛姜,分析完內(nèi)存堆棧后,會直接生成一個(gè)Notification晾虑,同時(shí)還會保留一份dump出來的堆棧信息。但是仅叫,這個(gè)堆棧信息是不可讀的,我們只要把他轉(zhuǎn)換為可讀信息糙捺,然后保存就好了诫咱。

代碼:就是重寫DisplayLeakService.java文件中的afterDefaultHandling這個(gè)方法。完整的工程源碼請參考git地址:https://github.com/hhhqq/leakcanary/tree/master/leakcanary-android/src/main/java/com/squareup/leakcanary

/**

* You can override this method and do a blocking call to a server to upload the leak trace and

* the heap dump. Don't forget to check {@link AnalysisResult#leakFound} and {@link

* AnalysisResult#excludedLeak} first.

*/

protected voidafterDefaultHandling(HeapDump heapDump,AnalysisResult result,String leakInfo) {

booleanshouldSaveResult = result.leakFound|| result.failure!=null;

if(shouldSaveResult) {

saveResult2(heapDump,result,leakInfo);

}

}

private booleansaveResult2(HeapDump heapDump,AnalysisResult result,String leakInfo) {

File resultFile =newFile(heapDump.heapDumpFile.getParentFile(),

heapDump.heapDumpFile.getName() +".leakinfo");

FileOutputStream fos =null;

try{

fos =newFileOutputStream(resultFile);

fos.write(leakInfo.getBytes());

return true;

}catch(IOException e) {

CanaryLog.d(e,"Could not save leakInfo analysis result to disk.");

}finally{

if(fos !=null) {

try{

fos.close();

}catch(IOException ignored) {

}

}

}

return false;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洪灯,一起剝皮案震驚了整個(gè)濱河市坎缭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌签钩,老刑警劉巖掏呼,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異铅檩,居然都是意外死亡憎夷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進(jìn)店門昧旨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拾给,“玉大人祥得,你說我怎么就攤上這事〗茫” “怎么了级及?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長额衙。 經(jīng)常有香客問我饮焦,道長,這世上最難降的妖魔是什么窍侧? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任县踢,我火速辦了婚禮,結(jié)果婚禮上疏之,老公的妹妹穿的比我還像新娘殿雪。我一直安慰自己,他們只是感情好锋爪,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布丙曙。 她就那樣靜靜地躺著,像睡著了一般其骄。 火紅的嫁衣襯著肌膚如雪亏镰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天拯爽,我揣著相機(jī)與錄音索抓,去河邊找鬼。 笑死毯炮,一個(gè)胖子當(dāng)著我的面吹牛逼肯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播桃煎,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼篮幢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了为迈?” 一聲冷哼從身側(cè)響起三椿,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎葫辐,沒想到半個(gè)月后搜锰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡耿战,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年蛋叼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剂陡。...
    茶點(diǎn)故事閱讀 40,865評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鸦列,死狀恐怖租冠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情薯嗤,我是刑警寧澤顽爹,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站骆姐,受9級特大地震影響镜粤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜玻褪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一肉渴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧带射,春花似錦同规、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至灿里,卻和暖如春关炼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匣吊。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工儒拂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人色鸳。 一個(gè)月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓社痛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親命雀。 傳聞我的和親對象是個(gè)殘疾皇子蒜哀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容