Android內(nèi)存泄漏二

轉(zhuǎn)載:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=62&highlight=%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A%E4%B8%89%E9%83%A8%E6%9B%B2%E4%B9%8B%E6%8E%92%E6%9F%A5%E6%96%B9%E6%B3%95%E7%AF%87

最原始的內(nèi)存泄露測(cè)試
重復(fù)多次操作關(guān)鍵的可疑的路徑,從內(nèi)存監(jiān)控工具中觀察內(nèi)存曲線,是否存在不斷上升的趨勢(shì)且不會(huì)在程序返回時(shí)明顯回落
。這種方式可以發(fā)現(xiàn)最基本,也是最明顯的內(nèi)存泄露問題抖坪,對(duì)用戶價(jià)值最大,操作難度小,性價(jià)比極高家夺。
MAT內(nèi)存分析工具2.1 MAT分析heap的總內(nèi)存占用大小來(lái)初步判斷是否存在泄露
在Devices 中,點(diǎn)擊要監(jiān)控的程序伐弹。
點(diǎn)擊Devices視圖界面中最上方一排圖標(biāo)中的“Update Heap”
點(diǎn)擊Heap視圖
點(diǎn)擊Heap視圖中的“Cause GC”按鈕
到此為止需檢測(cè)的進(jìn)程就可以被監(jiān)視拉馋。


Heap視圖中部有一個(gè)Type叫做data object,即數(shù)據(jù)對(duì)象惨好,也就是我們的程序中大量存在的類類型的對(duì)象煌茴。在data object一行中有一列是“Total Size”,其值就是當(dāng)前進(jìn)程中所有Java數(shù)據(jù)對(duì)象的內(nèi)存總量日川,一般情況下蔓腐,這個(gè)值的大小決定了是否會(huì)有內(nèi)存泄漏×渚洌可以這樣判斷:
進(jìn)入某應(yīng)用回论,不斷的操作該應(yīng)用,同時(shí)注意觀察data object的Total Size值分歇,正常情況下Total Size值都會(huì)穩(wěn)定在一個(gè)有限的范圍內(nèi)透葛,也就是說(shuō)由于程序中的的代碼良好,沒有造成對(duì)象不被垃圾回收的情況卿樱。
所以說(shuō)雖然我們不斷的操作會(huì)不斷的生成很多對(duì)象僚害,而在虛擬機(jī)不斷的進(jìn)行GC的過(guò)程中,這些對(duì)象都被回收了,內(nèi)存占用量會(huì)會(huì)落到一個(gè)穩(wěn)定的水平萨蚕;反之如果代碼中存在沒有釋放對(duì)象引用的情況靶草,則data object的Total Size值在每次GC后不會(huì)有明顯的回落。隨著操作次數(shù)的增多Total Size的值會(huì)越來(lái)越大岳遥,直到到達(dá)一個(gè)上限后導(dǎo)致進(jìn)程被殺掉奕翔。
2.2 MAT分析hprof來(lái)定位內(nèi)存泄露的原因所在。
這是出現(xiàn)內(nèi)存泄露后使用MAT進(jìn)行問題定位的有效手段浩蓉。
A)Dump出內(nèi)存泄露當(dāng)時(shí)的內(nèi)存鏡像hprof派继,分析懷疑泄露的類:

B)分析持有此類對(duì)象引用的外部對(duì)象

C)分析這些持有引用的對(duì)象的GC路徑

D)逐個(gè)分析每個(gè)對(duì)象的GC路徑是否正常

從這個(gè)路徑可以看出是一個(gè)antiRadiationUtil工具類對(duì)象持有了MainActivity的引用導(dǎo)致MainActivity無(wú)法釋放。此時(shí)就要進(jìn)入代碼分析此時(shí)antiRadiationUtil的引用持有是否合理(如果antiRadiationUtil持有了MainActivity的context導(dǎo)致節(jié)目退出后MainActivity無(wú)法銷毀捻艳,那一般都屬于內(nèi)存泄露了)驾窟。
2.3 MAT對(duì)比操作前后的hprof來(lái)定位內(nèi)存泄露的根因所在。
為查找內(nèi)存泄漏认轨,通常需要兩個(gè) Dump結(jié)果作對(duì)比绅络,打開 Navigator History面板,將兩個(gè)表的 Histogram結(jié)果都添加到 Compare Basket中去
A) 第一個(gè)HPROF 文件(usingFile > Open Heap Dump ).
B)打開Histogram view.
C)在NavigationHistory view里 (如果看不到就從Window >show view>MAT- Navigation History ), 右擊histogram然后選擇Add to Compare Basket .

D)打開第二個(gè)HPROF 文件然后重做步驟2和3.
E)切換到Compare Basket view, 然后點(diǎn)擊Compare the Results (視圖右上角的紅色”!”圖標(biāo))嘁字。

F)分析對(duì)比結(jié)果

可以看出兩個(gè)hprof的數(shù)據(jù)對(duì)象對(duì)比結(jié)果恩急。通過(guò)這種方式可以快速定位到操作前后所持有的對(duì)象增量,從而進(jìn)一步定位出當(dāng)前操作導(dǎo)致內(nèi)存泄露的具體原因是泄露了什么數(shù)據(jù)對(duì)象纪蜒。
注意:
如果是用 MAT Eclipse 插件獲取的 Dump文件衷恭,不需要經(jīng)過(guò)轉(zhuǎn)換則可在MAT中打開,Adt會(huì)自動(dòng)進(jìn)行轉(zhuǎn)換纯续。
而手機(jī)SDk Dump 出的文件要經(jīng)過(guò)轉(zhuǎn)換才能被 MAT識(shí)別随珠,Android SDK提供了這個(gè)工具 hprof-conv (位于 sdk/tools下)
首先,要通過(guò)控制臺(tái)進(jìn)入到你的 android sdk tools 目錄下執(zhí)行以下命令:./hprof-conv xxx-a.hprof xxx-b.hprof例如 hprof-conv input.hprof out.hprof此時(shí)才能將out.hprof放在eclipse的MAT中打開杆烁。
**手機(jī)管家內(nèi)存泄露每日監(jiān)控方案
**目前手機(jī)管家的內(nèi)存泄露每日監(jiān)控會(huì)自動(dòng)運(yùn)行并輸出是否存在疑似泄露的報(bào)告郵件,不論泄露對(duì)象的大小简卧。這其中涉及的核心技術(shù)主要是AspectJ兔魂,MLD自研工具(原理是虛引用)和UIAutomator。
3.1 AspectJ插樁監(jiān)控代碼
手機(jī)管家目前使用一個(gè)ant腳本加入MLD的監(jiān)控代碼举娩,并通過(guò)AspectJ的語(yǔ)法實(shí)現(xiàn)插樁析校。使用AspectJ的原因是可以靈活分離出項(xiàng)目源碼與監(jiān)控代碼,通過(guò)不同的編譯腳本打包出不同用途的安裝測(cè)試包:如果測(cè)試包是經(jīng)過(guò)Aspect插樁了MLD監(jiān)控代碼的話铜涉,那么運(yùn)行完畢后會(huì)輸出指定格式的日志文件智玻,作為后續(xù)分析工作的數(shù)據(jù)基礎(chǔ)。
3.2 MLD實(shí)現(xiàn)監(jiān)控核心邏輯
這是手機(jī)管家內(nèi)的一個(gè)工具工程芙代,正式打包不會(huì)打入吊奢,BVT等每日監(jiān)控測(cè)試包可以打入。打入后可以通過(guò)諸如addObject接口(通過(guò)反射去檢查是否含有該工具并調(diào)用)來(lái)加入需要監(jiān)控的檢測(cè)對(duì)象纹烹,這個(gè)工具會(huì)自動(dòng)在指定時(shí)機(jī)(如退出管家)去檢測(cè)該對(duì)象是否發(fā)生泄漏页滚。
這個(gè)內(nèi)存泄露檢測(cè)的基本原理是:
虛引用主要用來(lái)跟蹤對(duì)象被垃圾回收器回收的活動(dòng)召边。虛引用必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用(在虛引用函數(shù)就必須關(guān)聯(lián)指定)。當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí)裹驰,如果發(fā)現(xiàn)它還有虛引用隧熙,就會(huì)在回收對(duì)象的內(nèi)存之前,自動(dòng)把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中幻林。程序可以通過(guò)判斷引用隊(duì)列中是否已經(jīng)加入了虛引用贞盯,來(lái)了解被引用的對(duì)象是否將要被垃圾回收。
基于以上原理沪饺,MLD工具在調(diào)用接口addObject加入監(jiān)控類型時(shí)躏敢,會(huì)為該類型對(duì)象增加一個(gè)虛引用,注意虛引用并不會(huì)影響該對(duì)象被正乘婷觯回收父丰。因此可以在ReferenceQueue引用隊(duì)列中統(tǒng)計(jì)未被回收的監(jiān)控對(duì)象是否超過(guò)指定閥值。
利用PhantomReferences(虛引用)和ReferenceQueue(引用隊(duì)列)掘宪,當(dāng)PhantomReferences被加入到相關(guān)聯(lián)的ReferenceQueue時(shí)蛾扇,則視該對(duì)象已經(jīng)或處于垃圾回收器回收階段了。

MLD監(jiān)控原理核心
目前手機(jī)管家已對(duì)大部分類完成內(nèi)存泄露的監(jiān)控魏滚,包括各種activity镀首,service和view頁(yè)面等,務(wù)求在技術(shù)上能帶給用戶最順滑的產(chǎn)品體驗(yàn)鼠次。
接下來(lái)簡(jiǎn)單介紹下這個(gè)工具的判斷核心更哄。根據(jù)虛引用監(jiān)控到的內(nèi)存狀態(tài),需要通過(guò)多種策略來(lái)判斷是否存在內(nèi)存泄露腥寇。
(1)最簡(jiǎn)單的方式就是直接在加入監(jiān)控時(shí)就為該類型設(shè)定最大存在個(gè)數(shù)成翩,舉個(gè)例子,各個(gè)DAO對(duì)象理論上只能存在最多一個(gè)赦役,因此一旦出現(xiàn)兩個(gè)相同的DAO麻敌,那一般都是泄露了;
(2)第二種情況是在頁(yè)面退出程序退出時(shí)掂摔,檢索gc后無(wú)法釋放的對(duì)象列表术羔,這些對(duì)象類型也會(huì)成為內(nèi)存泄露的懷疑對(duì)象;
(3)最后一種情況比較復(fù)雜乙漓,基本原理是根據(jù)歷史操作判斷對(duì)象數(shù)量的增長(zhǎng)幅度级历。根據(jù)對(duì)象的增長(zhǎng)通過(guò)最小二乘法擬合出該對(duì)象類型的增長(zhǎng)速度,如果超過(guò)經(jīng)驗(yàn)值則會(huì)列入疑似泄露的對(duì)象列表叭披。
3.3 UIAutomator完成重復(fù)操作的自動(dòng)化
最后一步就很簡(jiǎn)單了寥殖。這么多反復(fù)的UI操作,讓人工來(lái)點(diǎn)就太浪費(fèi)人力了。我們使用UIAutomator來(lái)進(jìn)行自動(dòng)化操作測(cè)試扛禽。
目前手機(jī)管家的每日自動(dòng)化測(cè)試已覆蓋各個(gè)功能的主路徑锋边,并通過(guò)配置文件的方式來(lái)靈活驅(qū)動(dòng)用例的增刪改查,最大限度保證了隨著版本推移用例的復(fù)用價(jià)值编曼。
至此手機(jī)管家的內(nèi)存泄露測(cè)試方案介紹完畢豆巨,也歡迎各路牛人交流溝通更多更強(qiáng)的內(nèi)存泄露工具盒方案!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掐场,一起剝皮案震驚了整個(gè)濱河市往扔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌熊户,老刑警劉巖萍膛,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異嚷堡,居然都是意外死亡蝗罗,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門蝌戒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)串塑,“玉大人,你說(shuō)我怎么就攤上這事北苟∽耍” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵友鼻,是天一觀的道長(zhǎng)傻昙。 經(jīng)常有香客問我,道長(zhǎng)彩扔,這世上最難降的妖魔是什么妆档? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮虫碉,結(jié)果婚禮上贾惦,老公的妹妹穿的比我還像新娘。我一直安慰自己蔗衡,他們只是感情好纤虽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布乳绕。 她就那樣靜靜地躺著绞惦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪洋措。 梳的紋絲不亂的頭發(fā)上济蝉,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼王滤。 笑死贺嫂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雁乡。 我是一名探鬼主播第喳,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼踱稍!你這毒婦竟也來(lái)了曲饱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤珠月,失蹤者是張志新(化名)和其女友劉穎扩淀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啤挎,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驻谆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庆聘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胜臊。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖掏觉,靈堂內(nèi)的尸體忽然破棺而出区端,到底是詐尸還是另有隱情,我是刑警寧澤澳腹,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布织盼,位于F島的核電站衅檀,受9級(jí)特大地震影響拄氯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赫舒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一羊娃、第九天 我趴在偏房一處隱蔽的房頂上張望唐全。 院中可真熱鬧,春花似錦蕊玷、人聲如沸邮利。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)延届。三九已至,卻和暖如春贸诚,著一層夾襖步出監(jiān)牢的瞬間方庭,已是汗流浹背厕吉。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留械念,地道東北人头朱。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像龄减,于是被迫代替她去往敵國(guó)和親项钮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

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