内存测试入门
1.1新手入門
當軟件實現了新功能后,準備發布版本前,往往需要進行一輪性能測試以確定沒有性能問題,這類測試通常包括功能的流暢度,電量消耗和內存使用情況等。
由于內存組成的復雜性,實際上并沒有簡單通用的方法就能夠發現所有的內存問題。下面的章節里,我們會圍繞一組案例展開,通過對案例的分析講解各種內存測試的工具和方法。這些例子都是從真實的測試案例中提取的,經過加工后使得問題表現的更加明顯。
接下來我們以一個最常見的內存泄漏開始,作為最典型的內存問題,類似的情況可能在無數應用的無數版本中出現過,而且還會不斷的在新版本里出現。對于這樣的問題,我們必須要準確識別出來。
在大部分應用中,經常會有一類功能是需要加載附加資源的,比如顯示從網絡下載的文本或圖片。這類功能往往需要在內存中存放要使用的資源對象,退出該功能后,就需要將這些資源對象清空。如果忘了清理,或者是代碼原因造成的清理無效,就會形成內存泄漏。我們的測試任務就是保證功能的正常,并且不會有遺留的內存對象造成泄漏。
要開始進行性能測試,測試工具是必不可少的。我們一般都會優先使用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)了。
1.1.1使用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的代碼部分哪里有問題,從而快速的修復問題。
注:轉載自騰訊Bugly
總結
- 上一篇: 如何在Win10下安装MySQL 5.7
- 下一篇: 网络压线钳的实验报告_RJ45网线制作实