本文來自於騰訊優測公衆號(wxutest),未經做者贊成,請勿轉載,原文地址:http://mp.weixin.qq.com/s/1_FKMbi1enpcKMqto-o_FQjava
做者:騰訊TMQ專項測試團隊數組
最近小優據說,隔壁的騰訊TMQ團隊出了一本新書——《移動App性能評測與優化》,便借閱了一原本讀,讀完感受寫得確實很贊。這本書體系化地介紹了移動應用性能評測與優化的方方面面,如內存,電量,流暢度,導航,網絡優化和安裝包瘦身等,強烈推薦你們閱讀~微信
小優從書中摘取了第一章 「越用越卡爲哪般——如何下降App的待機內存」 的內容。本章介紹了各類內存使用狀況分析的方法和一些優化技巧,讓你們可以準確地瞭解應用內存的消耗狀況,找出存在的內存問題,並在開發過程當中儘可能節約使用內存。本章共5節,本篇爲第1節的入門內容,一塊兒來看看吧!網絡
在智能手機興起的這幾年中,咱們體驗到了手機內存從256M到4G的巨大變化,進程可用的內存也從僅有16/32M到如今可使用2G以上的內存。與此同時,應用的功能也日益複雜,也有跟多的進程在同時運行,須要協做和互相切換的應用愈來愈多。app
在硬件資源增加後,應用開發者們會盡可能使用這些資源來實現更多的功能和效果,所以咱們面對着各類大量消耗內存的應用,依然會感受到內存是稀缺資源。咱們任然須要須要每一個應用開發者瞭解內存的消耗狀況,並儘可能節約使用內存。框架
當軟件實現了新功能後,準備發佈版本前,每每須要進行一輪性能測試以肯定沒有性能問題,這類測試一般包括功能的流暢度,電量消耗和內存使用狀況等。工具
因爲內存組成的複雜性,實際上並無簡單通用的方法就可以發現全部的內存問題。下面的章節裏,咱們會圍繞一組案例展開,經過對案例的分析講解各類內存測試的工具和方法。這些例子都是從真實的測試案例中提取的,通過加工後使得問題表現的更加明顯。性能
接下來咱們以一個最多見的內存泄漏開始,做爲最典型的內存問題,相似的狀況可能在無數應用的無數版本中出現過,並且還會不斷的在新版本里出現。對於這樣的問題,咱們必需要準確識別出來。測試
在大部分應用中,常常會有一類功能是須要加載附加資源的,好比顯示從網絡下載的文本或圖片。這類功能每每須要在內存中存放要使用的資源對象,退出該功能後,就須要將這些資源對象清空。若是忘了清理,或者是代碼緣由形成的清理無效,就會造成內存泄漏。咱們的測試任務就是保證功能的正常,而且不會有遺留的內存對象形成泄漏。優化
要開始進行性能測試,測試工具是必不可少的。咱們通常都會優先使用SDK/IDE自帶的工具,所以首先會想到的工具就是和IDE集成在一塊兒的Android Device Monitor/Android Studio了。
大多數狀況下,功能代碼都是由Dalvik虛擬機裏執行的Java代碼實現的,所以主要的內存消耗也是由Java代碼使用new分配的內存。Android Device Monitor和Android Studio可以方便的觀察Heap Alloc部分的大小,進行初步的統計,還可以觀察到GC發生時的內存變化狀況。
圖1-1 使用DDMS觀察應用的內存消耗
圖1-2 使用Android Studio觀察應用的內存消耗
在圖1-1中,咱們可以看到應用當前消耗了多少內存,以及各類不一樣類型對象的初步統計。在圖1-2中,Android Studio更進一步的將內存數據進行了圖形化,這樣就能過方便地看出GC(垃圾回收)狀況和明顯的內存趨勢。若是存在明顯的內存泄漏,那麼在圖中就會表現爲隨着功能的反覆使用,內存值不斷的升高,即便出現GC也無法降下來,如圖1-3所示。
圖1-3典型的內存泄漏
發現了內存泄漏,一般就能夠交給開發去處理了。但咱們能作的並不僅是丟一個問題描述和復現路徑過去,而是利用手頭的工具,得到一些更詳細的數據,可以使你們更快的定位和解決問題。這樣分析內存得到詳細數據的首選工具就是Eclipse Memory Analyzer(MAT)了。
Eclipse Memory Analyzer(MAT)是使用很是普遍的Java內存分析工具,功能強大。已經有不少關於它的詳細教程,在本書中就再也不細述用法。本節內容主要介紹使用MAT在分析Android應用時的一些經常使用技巧。
一般咱們用MAT打開hprof文件後,可以在首頁看到Top Consumers和Component Report等功能,使用這些功能可以快速定位一些大塊的內存消耗。但對於Android應用的hprof文件,咱們在使用了Top Consumers統計使用狀況後,每每只能看到如圖1-4所示的狀況:
圖1-4 使用MAT分析內存構成
系統的資源類佔據了很大一部分的內存,而其他的前幾名也每每是系統類。這是因爲從虛擬機角度不會區分系統框架和應用自身的對象,後面的1.4.3節會詳細說明出現這種現象的緣由。
爲了去除這部分對分析的干擾,咱們在用Android SDK提供的hprof-conv轉換時須要增長一個參數:
hprof-conv [-z] <infile><outfile> -z: exclude non-app heaps, such as Zygote
另外一種可替代的方法是使用OQL。若是hprof文件是已經轉換過的,能夠在數據中尋找應用的Application類對象,將對象地址轉換爲10進制後輸入如下查詢語句:
select * from instanceof java.lang.Object s where s.@objectAddress > 1107296256
使用-z參數轉換或OQL查詢後獲得的對象集合就只包含應用代碼分配的部分了。在此基礎上使用MAT提供的Top Consumers和Component Report等功能就可以獲得比較準確的結果。如圖1-5所示,沒有了系統類所佔內存的干擾,只有應用自身代碼建立的對象,對於發現內存問題比較有幫助。
圖1-5分離以後再次分析內存構成
對於通常的內存泄露類問題,使用以上方法後經過MAT提供的分析報告就很容易就會識別出來。在咱們以往的測試經歷中,用這種方法發現了上百次的內存問題。這些內存每每是加載後忘了釋放的Bitmap,臨時生成的byte數組和文件緩衝區,包含Handler的Activity等等。
接下來咱們看一個真實的應用測試案例。在這個案例裏,有些位圖在使用完以後因爲種種緣由,一直沒有銷燬而存在ImageLoader裏,使用一段時間後ImageLoader會變得愈來愈龐大。使用上面介紹的方法去除了系統的影響後,MAT的泄露報告給出告終果,如圖1-6所示,ImageLoader消耗了接近1/3的內存。
圖1-6 MAT識別出來的問題
有了這樣的數據,接下來就能夠結合圖片追蹤代碼,看引用到ImageLoader的代碼部分哪裏有問題,從而快速的修復問題。
下週咱們將帶來規範測試流程及常見問題
更多精彩內容歡迎關注騰訊優測的微信公衆帳號:
騰訊優測是專業的移動雲測試平臺,爲應用、遊戲、H5混合應用的研發團隊提供產品質量檢測與問題解決服務。不只在線上平臺提供app自動化測試、雲真機遠程操控與調試、私有自動化測試工具XTest等多種質量檢測工具,更爲VIP客戶配備了專家團隊提供定製化綜合測試解決方案。