本文來自於騰訊優測公衆號(wxutest),未經做者贊成,請勿轉載,原文地址:https://mp.weixin.qq.com/s/806TiugiSJvFI7fH6eVA5w數組
做者:騰訊TMQ專項測試團隊緩存
最近小優據說,隔壁的騰訊TMQ團隊出了一本新書——《移動App性能評測與優化》,便借閱了一本,讀完感受寫得確實很贊。這本書體系化地介紹了移動應用性能評測與優化的方方面面,如內存,電量,流暢度,導航,網絡優化和安裝包瘦身等,強烈推薦你們閱讀~微信
小優從書中摘取了第一章 「越用越卡爲哪般——如何下降App的待機內存」 的內容。網絡
本章介紹了各類內存使用狀況分析的方法和一些優化技巧,讓你們可以準確地瞭解應用內存的消耗狀況,找出存在的內存問題,並在開發過程當中儘可能節約使用內存。app
本章共5節,上週給你們推送了第1節「內存測試新手入門」的內容,本週咱們繼續講解「規範測試流程及常見問題」,一塊兒來看看吧!函數
最開始進行內存測試時,咱們可能還有些摸不着頭腦,試着找了些工具,看了看教程就開始動手了。有時候由於問題比較明顯,就真的發現了問題。再以後遇到相似的測試需求,咱們就會按上次的經驗去作。有時候可能發現問題,也可能發現不了,還有些時候發現是甚至是在白費功夫。由於隨着明顯的問題逐漸被找出來,剩下的有都是更加複雜而不太明顯的問題,甚至有些更是能夠歸屬到優化範疇或者產品策略以內,而再也不是簡單的內存問題。工具
隨着經驗的逐漸增長,咱們逐漸意識到,之前的不少測試方法都是隨機亂測。對於較爲成熟的軟件,這類方法的測試有效性每每比較低,運氣好了纔會遇到問題。若是是較深層次的問題要麼遇不到,要麼遇到了也找不出緣由。所以,有必要總結出一套成熟的流程方法,可以考慮到各個方面,提升測試的有效性。性能
因爲內存測試屬於性能測試,Android系統又和Linux有不少相通之處。所以咱們能夠參考常見的Linux性能測試方法和指標,來制定客戶端性能測試方案。常見的測試方法包括Monkey/UIAutomator類的常規壓力測試,大數據/操做的峯值壓力測試,長時間運行的穩定性測試等。這些方法均可以疊加在內存測試的方案中,觀察這類場景下的應用內存狀況,常常可以發現相似內存泄漏或OOM的問題。測試
參考了常見性能測試的方案,以及總結了以往對內存性能測試的經驗後,咱們總結出了一套進行內存測試的經驗流程,供讀者在制定測試計劃時參考。大數據
一般用來進行內存測試的版本是純淨版本,不該該附加多餘的Log和調試用組件。例若有些狀況下,爲了測試界面延遲/函數執行時間等性能,會加入一些樁點代碼。在內存測試中這些代碼是沒必要要的,它們可能會分配臨時內存,引發更多的GC,致使應用出現運行緩慢、卡頓等現象。
測試場景一般有兩類,一類是當前有新開發或改動的某項功能,須要對該功能進行性能測試。所以測試場景主要針對該功能組織,包括功能的開啓前,運行,結束後等測試點。
另外一類是總體性能,考察應用的常見場景,在綜合使用狀況下的性能指標。測試場景應當包括啓動後待機,切換到後臺,執行主要功能,以及反覆執行各功能後。
在各種場景中,常常作爲測試重點的有:
選取了測試場景後,用例設計也要考慮內存測試的特色。一些常見的方法是:
因爲GC和廣播機制的存在,應用內存一般都在不停得波動,幅度可能會達到幾百K,所以執行時須要考慮這種狀況。在採集數據時,須要屢次採集並計算平均值。
執行完成中,咱們就能夠根據數據進行比較初步的分析以肯定方向。一方面是咱們熟悉的Dalvik Heap部分,既由Java代碼直接分配的內存,能夠經過IDE直接觀察到使用狀況,也可使用MAT進行細緻的分析。
另外一方面,假如咱們發現Dalvik Heap沒怎麼增加,而其餘部分增加了許多,這種狀況下的分析就要複雜一些,咱們留待後面的章節再說。
隨着測試的執行,隨之而來的就是一大堆產生的數據,對產生的數據進行分析,找出可能存在的問題,以及問題可能的緣由是接下來的重點。
因爲大部分Android應用是Java代碼開發的,因此Dalvik Heap內存出現問題也是最多見的狀況。常見的現象有如下幾種:
隨着功能的反覆執行,Heap內存一直在持續增加。這種狀況一般是出現了內存泄露,這種狀況最適合用LeakCanary等泄露檢查工具進行白盒測試分析。
代碼執行時出現了頻繁的GC,Heap Alloc內存大幅度波動。這種狀況一般是分配了許多臨時變量或數組,隨後又被迅速回收,這種狀況在肯定具體場景後適合使用Heap Viewer / Allocation Tracker等工具來查看具體分配的對象。
每次啓動應用後,Heap內存相比之前版本穩定增加。這種狀況一般出如今啓動後待機或使用某功能後,多是由新功能及代碼改動引入的固定內存增加。這種狀況適合獲取Heap Dump後進行多版本或功能使用先後的對此,可以迅速找到增加緣由。
Heap Alloc變化不大,但進程的Dalvik Heap PSS內存明顯增長。這種狀況比較少見,是因爲分配了大量小對象形成的內存碎片,在後面的章節裏會詳細講解,具體內容請見下一節。
在1.1節,咱們已經介紹了出現內存泄漏時的問題現象及分析方法,在這裏咱們再以一個真實的例子介紹常見的幾種內存問題和分析方法。
這是發生在手機管家4.x的某個版本上的案例,新版中加入了一些功能,開發人員估計新功能可能會分配幾十到幾百K的內存,所以咱們來進行內存方面的測試驗證。當新功能的代碼合入後,咱們發現應用啓動後的內存增加超過了2M,這可大大超出了全部人的預期,必定是有什麼地方出了嚴重的問題。
因爲新加入了好幾個功能,所以要逐個去排查。若是某個新功能的代碼都在同一個package下,那麼就可使用MAT的過濾功能來驗證這部分代碼是否使用了內存。如圖1-7所示:
圖1-7 使用MAT的過濾功能
通過一番篩選排查,發現內存中多出了一些新對象,多消耗了約300K內存,目前這並不能解釋內存增加了2M的緣由。但仔細檢查多出來的對象並清理掉不用的部分也是有幫助的。
通過檢查,這部份內存是其餘新功能使用的。對此咱們須要進一步確認,這些對象是不是有用的,仍是臨時建立的。對於臨時建立再也不使用的能夠主動銷燬,而保存着信息將要用到的也能夠進行進行壓縮裁剪,以進一步減小佔用的內存。
在以上排查中,咱們確實發現了一些問題,但將一些不用的對象清理後再執行測試,整體內存並無出現明顯的減小。如今看來,Dalvik Heap裏分配的內存並無增長許多,說明問題是不能只在Dalivk Heap裏就解決的。也許是別的部分出現了問題?接下面咱們就繼續深挖下去。
通過上一輪的優化,在內存監視器裏新版本的Heap內存表現已經比較好了,新功能只消耗了幾十K到上百K內存。可是要注意的是,Heap內存並非應用的所有,咱們在設置或其餘管理工具裏看到的應用內存是應用整個進程的內存使用量。也有可能出現Heap部分徹底沒有增加而其餘部分增加的狀況。
要觀察進程的內存使用狀況,就須要用到其餘的觀測工具,Android裏最經常使用的觀察進程內存的方法就是dumpsys meminfo <package name|pid>
命令。
對咱們的新版應用執行該命令,可以獲得如下的輸出結果:
在以上輸出結果中,左邊Pss Total列的數據標識進程各部分對真實物理內存的消耗,左下角的TOTAL值就是咱們在各類管理工具裏看到的應用內存消耗。
而Android Studio等工具裏顯示的內存值,在這裏是Dalvik Heap Alloc部分。根據以上的數據,咱們能夠看到Dalvik Heap和Heap Alloc不是相等的,並且除了Dalvik Heap以外,還有其餘不少部分也會消耗內存。
這時候咱們再對比一下舊版,看看是否也如此:
這時候就會發現問題了,Heap Alloc沒增長多少,但Dalvik Heap Pss卻漲了許多。而其餘部分基本保持不變或有少許增加。可見問題仍是出現Dalvik Heap部分,但只靠檢查分配的對象是看不出來問題的。
Java代碼的內存分配和釋放都是由虛擬機管理的,那麼這個問題會是虛擬機的問題嗎?下一節咱們來繼續經過虛擬機部分機制的探索來探索這些內存增加的緣由。
更多精彩內容歡迎關注騰訊優測的微信公衆帳號:
騰訊優測是專業的移動雲測試平臺,爲應用、遊戲、H5混合應用的研發團隊提供產品質量檢測與問題解決服務。不只在線上平臺提供app自動化測試、雲真機遠程操控與調試、私有自動化測試工具XTest等多種質量檢測工具,更爲VIP客戶配備了專家團隊提供定製化綜合測試解決方案。