溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

案例:隱秘而低調(diào)的內(nèi)存泄露(OOM)

發(fā)布時(shí)間:2020-06-10 03:15:56 來(lái)源:網(wǎng)絡(luò) 閱讀:2962 作者:小強(qiáng)測(cè)試 欄目:軟件技術(shù)

內(nèi)存泄露測(cè)試的整個(gè)過(guò)程如下:

  • 在手機(jī)里啟動(dòng)被測(cè)APP并打開(kāi)DDMS。

  • 在DDMS中選中【com.example.android.hcgallery】之后單擊按鈕【show heap updates】,然后切換到標(biāo)簽頁(yè)【VM Heap】,再單擊按鈕【Cause GC】。

  • 不斷操作APP,并觀察Heap。經(jīng)過(guò)一段時(shí)間的操作我們發(fā)現(xiàn)不論是%Used還是data object的Total Size都在不斷增加,如圖。正常情況下Total Size會(huì)穩(wěn)定在一定范圍內(nèi)。

案例:隱秘而低調(diào)的內(nèi)存泄露(OOM)

圖 VM Heap 1

  • 即使進(jìn)行Cause GC之后仍會(huì)繼續(xù)增加,如圖

案例:隱秘而低調(diào)的內(nèi)存泄露(OOM)

圖 VM Heap 2

  • 此時(shí)我們懷疑如果長(zhǎng)期下去可能有內(nèi)存泄露的可能性,為了進(jìn)一步分析我們單擊按鈕【Dump HPROF File】,得到一個(gè)后綴為hprof的文件(生成該文件的時(shí)間較長(zhǎng),請(qǐng)耐心等待)。

  • 使用命令hprof-conv將得到的hprof文件轉(zhuǎn)化為標(biāo)準(zhǔn)的hprof,這樣MAT才能識(shí)別。

  • 使用MAT打開(kāi)轉(zhuǎn)化之后的hprof文件,選擇圖中的【Leak Suspects Report】即可。之后你會(huì)看到一個(gè)概要信息,如圖。它只是給出一個(gè)宏觀的概念,告訴你某些問(wèn)題的占比,對(duì)于分析并沒(méi)有實(shí)質(zhì)性的幫助。

案例:隱秘而低調(diào)的內(nèi)存泄露(OOM)

案例:隱秘而低調(diào)的內(nèi)存泄露(OOM)


  • 單擊柱形圖標(biāo)按鈕【Histogram】會(huì)生成一個(gè)視圖,它顯示的是類(lèi)實(shí)例的列表,其中Shallow Heap代表對(duì)象自身占用的內(nèi)存大小,不包括它引用的對(duì)象。Retained Heap代表當(dāng)前對(duì)象大小和當(dāng)前對(duì)象可直接或間接引用到的對(duì)象的大小總和。

  • 在Shallow Heap列進(jìn)行從大到小的排序,我們發(fā)現(xiàn)byte[]占比最大,選中之后右鍵依次選擇【List objects】>【with incoming referenes】進(jìn)行鉆取,如圖。

案例:隱秘而低調(diào)的內(nèi)存泄露(OOM)

圖 Histogram視圖

  • 再次按照Shallow Heap列進(jìn)行從大到小的排序,選擇一個(gè)較大的對(duì)象并依次展開(kāi)它的路徑,如圖。這里我們關(guān)注自己寫(xiě)的代碼,也就是com.example.android.hcgallery.ContentFragment,我們發(fā)現(xiàn)mBitmap比較可疑。這種方法適合對(duì)代碼比較熟悉的朋友。

案例:隱秘而低調(diào)的內(nèi)存泄露(OOM)

圖 with incoming references

  • 除了上述方法之外你也可以通過(guò)排除弱引用來(lái)分析,這樣能減少干擾因素。先按照Retained Heap從大到小排序,之后右鍵最大的,依次選擇【Path To GC Roots】>【exclude weak references】,得到如圖的數(shù)據(jù)。發(fā)現(xiàn)sBitmapCache這個(gè)變量占的比例較大,可能有問(wèn)題。

案例:隱秘而低調(diào)的內(nèi)存泄露(OOM)

圖 exclude weak references

小強(qiáng)課堂 在Java中存在強(qiáng)引用、弱引用、軟引用,這里給大家做一個(gè)普及:

強(qiáng)引用:垃圾回收不會(huì)回收它,需要我們主動(dòng)設(shè)置為null。

弱引用:顧名思義比較弱,當(dāng)垃圾回收發(fā)現(xiàn)它只具有弱引用對(duì)象時(shí),不管當(dāng)前內(nèi)存空間是什么情況,都會(huì)進(jìn)行回收。

軟引用:如果它只具有軟引用對(duì)象時(shí),內(nèi)存空間足夠,垃圾回收器就不會(huì)回收。但如果內(nèi)存空間不足了,就會(huì)回收。

  • 之后排查代碼發(fā)現(xiàn)sBitmapCache是static HashMap,mBitmap使用完成之后沒(méi)有recycle掉。

  • 最后修改代碼,在mBitmap != null時(shí)進(jìn)行mBitmap.recycle()。


這樣一步步做下來(lái)至少你不會(huì)覺(jué)得混亂,而是有規(guī)可循。另外,有些內(nèi)存泄露的分析可能沒(méi)法一次性分析出來(lái),需要多次,這就考驗(yàn)大家的耐心了。其實(shí)只要記住,分析要有規(guī)可循,耐心必不可少,任何難題都可以解決的。


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI