您好,登錄后才能下訂單哦!
內存泄露測試的整個過程如下:
在手機里啟動被測APP并打開DDMS。
在DDMS中選中【com.example.android.hcgallery】之后單擊按鈕【show heap updates】,然后切換到標簽頁【VM Heap】,再單擊按鈕【Cause GC】。
不斷操作APP,并觀察Heap。經過一段時間的操作我們發現不論是%Used還是data object的Total Size都在不斷增加,如圖。正常情況下Total Size會穩定在一定范圍內。
圖 VM Heap 1
即使進行Cause GC之后仍會繼續增加,如圖
圖 VM Heap 2
此時我們懷疑如果長期下去可能有內存泄露的可能性,為了進一步分析我們單擊按鈕【Dump HPROF File】,得到一個后綴為hprof的文件(生成該文件的時間較長,請耐心等待)。
使用命令hprof-conv將得到的hprof文件轉化為標準的hprof,這樣MAT才能識別。
使用MAT打開轉化之后的hprof文件,選擇圖中的【Leak Suspects Report】即可。之后你會看到一個概要信息,如圖。它只是給出一個宏觀的概念,告訴你某些問題的占比,對于分析并沒有實質性的幫助。
單擊柱形圖標按鈕【Histogram】會生成一個視圖,它顯示的是類實例的列表,其中Shallow Heap代表對象自身占用的內存大小,不包括它引用的對象。Retained Heap代表當前對象大小和當前對象可直接或間接引用到的對象的大小總和。
在Shallow Heap列進行從大到小的排序,我們發現byte[]占比最大,選中之后右鍵依次選擇【List objects】>【with incoming referenes】進行鉆取,如圖。
圖 Histogram視圖
再次按照Shallow Heap列進行從大到小的排序,選擇一個較大的對象并依次展開它的路徑,如圖。這里我們關注自己寫的代碼,也就是com.example.android.hcgallery.ContentFragment,我們發現mBitmap比較可疑。這種方法適合對代碼比較熟悉的朋友。
圖 with incoming references
除了上述方法之外你也可以通過排除弱引用來分析,這樣能減少干擾因素。先按照Retained Heap從大到小排序,之后右鍵最大的,依次選擇【Path To GC Roots】>【exclude weak references】,得到如圖的數據。發現sBitmapCache這個變量占的比例較大,可能有問題。
圖 exclude weak references
小強課堂 在Java中存在強引用、弱引用、軟引用,這里給大家做一個普及:
強引用:垃圾回收不會回收它,需要我們主動設置為null。
弱引用:顧名思義比較弱,當垃圾回收發現它只具有弱引用對象時,不管當前內存空間是什么情況,都會進行回收。
軟引用:如果它只具有軟引用對象時,內存空間足夠,垃圾回收器就不會回收。但如果內存空間不足了,就會回收。
之后排查代碼發現sBitmapCache是static HashMap,mBitmap使用完成之后沒有recycle掉。
最后修改代碼,在mBitmap != null時進行mBitmap.recycle()。
這樣一步步做下來至少你不會覺得混亂,而是有規可循。另外,有些內存泄露的分析可能沒法一次性分析出來,需要多次,這就考驗大家的耐心了。其實只要記住,分析要有規可循,耐心必不可少,任何難題都可以解決的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。