真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Android內(nèi)存泄漏定位與解決-創(chuàng)新互聯(lián)

問題現(xiàn)象

成都創(chuàng)新互聯(lián)公司服務(wù)項目包括昌都網(wǎng)站建設(shè)、昌都網(wǎng)站制作、昌都網(wǎng)頁制作以及昌都網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,昌都網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到昌都省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

反復(fù)點擊被測試的Android App的toolbar界面,然后返回再點擊。在此重復(fù)過程中,發(fā)現(xiàn)到一定次數(shù)時,頁面打開速度變慢,有時達到5s,十分影響用戶體驗。該問題涉及app所采用的webview框架的所有界面,影響面大。

初步分析

加載界面慢,一般有2種情況:一是每次都慢,那么與該界面的布局(layout)效率或業(yè)務(wù)邏輯(主線程動畫/同步的業(yè)務(wù)邏輯)關(guān)系更大;另外一種是重復(fù)打開幾次,會遇到一次變慢,并且循環(huán)發(fā)生,根據(jù)多次內(nèi)存問題的分析經(jīng)驗,會與內(nèi)存泄漏關(guān)系更大。至于為何有如此的判斷依據(jù),下文會進行解釋。

該問題屬于后者,因此首先從內(nèi)存的角度進行分析。使用Android官方提供的DDMS工具,選中App所在進程,監(jiān)控該進程的堆內(nèi)存狀況,如下表所示,隨著重復(fù)打開界面次數(shù)的增加,堆內(nèi)存一直呈上升趨勢,而且,測試過程中,即使點擊DDMS的Gause GC(Garbage Collector 內(nèi)存垃圾回收)來主動觸發(fā)內(nèi)存垃圾回收,堆內(nèi)存也沒有下降。

Android內(nèi)存泄漏定位與解決

   從該圖可以判斷,無論是系統(tǒng)自發(fā)的GC或QA主動觸發(fā),對內(nèi)存都不會下降,說明有相當一部分對象被一直引用著,導(dǎo)致GC時不會去釋放這部分對象的內(nèi)存,而每打開一次界面,又會在堆上為新的對象分配內(nèi)存,最終結(jié)果就是內(nèi)存泄漏。

對內(nèi)存泄漏有了初步判斷后,下一步是使用MAT工具分析該場景所有對象的內(nèi)存占用和引用關(guān)系,從而定位出具體導(dǎo)致泄漏的類。首先同樣地重復(fù)打開該界面,在打開第5次、10次、20次的時候,分別dump出當時的hprof文件(相當于所有對象的內(nèi)存畫像),3個文件在MAT的sumary分析中,都指出DynamicBgDrawable這個類的對象存在內(nèi)存泄漏的風險

Android內(nèi)存泄漏定位與解決

   于是問題的分析有了下一步的目標。繼續(xù)使用MAT查看DynamicBgDrawable對象的引用鏈:

Android內(nèi)存泄漏定位與解決

   從上圖看出,GraphicContent這個類的mContents成員(WeakHashMap類型)是mBackground對象(DynamicBgDrawable類型)的root引用,這說明正是因為GraphicContent中mContents對mBackground的間接引用一直未釋放,才導(dǎo)致DynamicBgDrawable對象內(nèi)存的泄漏,到這里就可以從GraphicContent.java的代碼繼續(xù)尋找問題的原因了。

代碼&業(yè)務(wù)分析

Android內(nèi)存泄漏定位與解決

   從GraphicContent類的兩處代碼可以看出,GraphicContent一直持有著View,而WeakHashMap這個結(jié)構(gòu),如果作為key的View沒有被釋放,作為value的GraphicContent也不會被釋放,而這里的View,在實際運行時,傳的就是DynamicBgDrawable對象,所以形成DynamicBgDrawable與GraphicContent循環(huán)引用,互不釋放的局面,隨著重復(fù)地調(diào)用次數(shù)增多,無法釋放的對象越來越多,最終導(dǎo)致內(nèi)存泄漏。

真相大白

Android App是運行在Dalvik虛擬機之上的Java程序,Dalvik是Java虛擬機(JVM)針對Android改造的版本,許多機制沿襲了JVM的設(shè)計,包括內(nèi)存管理。對JVM的內(nèi)存管理和回收機制進行了解,能更深入地理解該Bug的分析手段和定位過程。

Android內(nèi)存泄漏定位與解決

以上是Java虛擬機(JVM)的內(nèi)存區(qū)域劃分,Java只能在堆中存放對象,而不能在棧上分配對象,所有運行時產(chǎn)生的對象全部都存放于堆中,包括數(shù)組。是一個線程的執(zhí)行區(qū)域, 它保存著一個線程中的方法的調(diào)用狀態(tài),也可以說,一個Java線程的運行狀態(tài),都由一個Java棧來保存。每個線程都會有自己的Java棧, 不會相互訪問其他Java棧中的數(shù)據(jù)。同時,基本數(shù)據(jù)類型也是在棧中保存,包括boolean、byte、char、short、int、float、long、double。所以在分析這個Bug時,只關(guān)心堆內(nèi)存,而不關(guān)心棧內(nèi)存。因為對象內(nèi)存的泄漏(溢出)只會發(fā)生在堆內(nèi)存上。

下面解釋開頭的問題:為什么概率性加載緩慢,更有可能與內(nèi)存相關(guān)。首先需要了解Dalvik虛擬機的內(nèi)存垃圾回收原理:

Android內(nèi)存泄漏定位與解決

   Dalvik中會維護一個對象的引用關(guān)系圖,如上圖所示,方塊代表一個對象,mark后的數(shù)字代表這個對象被持有的引用個數(shù)。當Dalvik進行GC時,首先會做“標記”,將每個對象被引用的次數(shù)進行標記。上圖中,Root是引用關(guān)系圖的起點,藍色方塊代表該對象被持有了引用,那么它的內(nèi)存不會被回收。白色方塊代表該對象沒有或即將不被持有引用?!睒擞洝边^程結(jié)束后,GC就進入”清除”過程,會把所有mark為0的對象內(nèi)存釋放掉,從而完成一次GC的操作。

 Android內(nèi)存泄漏定位與解決

   上圖就是GC進行“清除”操作前后的示意圖。可以看出,在回收前,連續(xù)的可用內(nèi)存較少,等同于碎片較多,在回收后,連續(xù)的可用內(nèi)存變多了。我們回到bug本身,由于每次打開界面,都會為新的對象分配內(nèi)存,于是上圖中的存活對象方塊會會越來越多,連續(xù)的未使用區(qū)域會越來越少,這時當下一次打開界面時,因為碎片過多,無法分配內(nèi)存給對象,特別是大對象,就會過早的引起GC。而對象越多,一次GC的時間會越長,從而加大了系統(tǒng)的負載,增加了App界面的調(diào)起時間。下一步,當完成GC后,如果有足夠的內(nèi)存可分配,則是較好的情況,如果像該Bug的情況,占用大片內(nèi)存的對象一直被引用著而不被GC釋放,在下一次打開界面時,Android系統(tǒng)就需要為這個App分配更大的堆內(nèi)存,以保證內(nèi)存分配成功。當內(nèi)存泄漏到一定程度,系統(tǒng)無法保證為App分配足夠內(nèi)存時,則內(nèi)存溢出(Out Of Memory, OOM)就會發(fā)生。

Android內(nèi)存泄漏定位與解決

   上圖解釋了界面概率性打開緩慢與內(nèi)存更相關(guān)的原因。圖中黑色的步驟都會增加界面的加載時間,上面的黑色步驟,是由于內(nèi)存碎片引起,會隨著打開次數(shù)增多,發(fā)生概率加大。下面的黑色步驟,是根據(jù)GC后App所生堆內(nèi)存大小相關(guān),每次打開界面的情況都會不一樣,因此,才會出現(xiàn)概率性的打開緩慢,從而為我們分析這種問題提供思路——就是開頭提到的,如果是概率性打開緩慢,可以優(yōu)先考慮和內(nèi)存問題相關(guān)。

解決方案

將mView改為弱引用,每次垃圾回收(GC)時,都會回收View對象,從而使WeakHashMap中的value(GraphicContent)對象也能自動得到釋放。

Android內(nèi)存泄漏定位與解決

總結(jié)

該Bug的分析和解決過程,具有典型的代表性,在實際項目中,有多個Android內(nèi)存泄漏的Bug,都是采用上述的定位方法和分析工具進行解決的,是一套通用且有效的Bug定位方案。而相互引用的問題,等價于死鎖情況,也是程序中典型的問題場景。弱引用的使用有效地解決業(yè)務(wù)和內(nèi)存泄漏的問題,在Android app的內(nèi)存泄漏和溢出的解決中,經(jīng)常會被采用,也可以作為Code Review的一個關(guān)注點進行推廣。

百度MTC是業(yè)界領(lǐng)先的移動應(yīng)用測試服務(wù)平臺,為廣大開發(fā)者在移動應(yīng)用測試中面臨的成本、技術(shù)和效率問題提供解決方案。同時分享行業(yè)領(lǐng)先的百度技術(shù),作者來自百度員工和業(yè)界領(lǐng)袖等。

>>如有問題,歡迎與我溝通

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


分享名稱:Android內(nèi)存泄漏定位與解決-創(chuàng)新互聯(lián)
本文鏈接:http://weahome.cn/article/dcijdi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部