Android內存泄露測試不再藍瘦,香菇
在進行 Android 內存泄露分析時,面對成千上萬個對象,你是否藍瘦 , 香菇?作為測試人員你在進行內存泄露測試之后,是否有勇氣告訴開發同事程序已經沒有內存泄露,可以放心發布了?
眾所周知,內存泄露測試難點在于準確的定位出泄露的對象。現在小哥有種方法通過一條命令就高效全面的得到 Android 程序內存泄露對象,讓你不再藍瘦,香菇!
1.Android內存泄露自動化分析方法
目前我知道的幾種常用的 Android 內存泄漏方案主要有 MAT 、騰訊內部開發的 Finder 、 LeakCanary 以及瀏覽器目前使用的方法。
幾種方法,我們通過以下的幾個緯度進行對比。
MAT | Finder | LeakCanary | QB 方案 | |
手動 / 自動 | 手動 | 手動 | 自動 | 自動 |
分析準確度 | 低 | 高 | 高 | 高 |
分析難度 | 高 | 中 | 低 | 低 |
分析效率 | 低 | 中 | 高 | 高 |
是否修改代碼 | 否 | 否 | 是 | 否 |
應用場景 | 所有 | 所有 | 部分 | 所有 |
最原始的 Java 內存泄露分析方式,是通過 MAT 將測試操作前后的 Hprof 文件進行對比,然后根據對比結果來嘗試識別出泄露對象,這種方法效率比較低。
如果使用騰訊的 Finder 工具來進行泄露分析,效率將會提高很多,但還是手動執行,也存在時間浪費的問題。
也可以使用 LeakCanary 或者騰訊自研的 LeakInspector 來測試,由于這兩個工具是自動分析,效率會更加高效。但需要修改代碼,把工具的 SDK 引入到工程中。此外針對不退出 Activity 的測試場景,不能很好的處理。
而我們的分析方法,一條命令就可以完成分析,并輸出詳細的泄露對象,以及調用關系。
從前面的表中可以看 LeakCanary 各方面都挺優秀,但是我們為什么沒有使用它呢?這是因為 QQ 瀏覽器很多場景都是在 MainActivity 中進行的,比如打開網頁,此時 MainActivity 并不會 Destroy ,直接使用 LeakCanary 無法進行泄漏分析,因此我們才考慮自己實現一個分析工具。
在 QQ 瀏覽器項目中,使用的分析工具叫做 HprofComparator ,這是我們自己開發的一個 Eclipse Application ,其原理與 Finder 的對比原理一致,但是加入了泄露分析的策略,可以通過命令行直接運行,更加的高效。
2.瀏覽器內存泄漏測試方案實施
1) 測試場景選擇
做內存泄漏測試一定要全面的測試才敢通知項目組放心發布,目前 QQ 瀏覽器選擇對所有的畫面進行泄漏排查。
內存出現泄漏的前提條件一定是有新的內存分配,所以測試場景會選擇有新對象創建的場景,并結合用戶的使用場景和頻率來確定優先級。測試場景主要有以下三種情況:
? 新畫面打開
由于新的畫面打開,就會創建新的 Activity ,并有許多其他對象被創建。
? 畫面旋轉
當屏幕旋轉時, Orientation 設置發生了改變,當前顯示的 Activity 會被重新創建。
? 滑動屏幕
滑動屏幕會使屏幕中顯示的對象(比如瀏覽器小說閱讀內容)創建。
2)內存泄漏分析
測試方法就是重復運行以上選擇的場景,將整個測試過程分幾個階段獲取到 Hprof 文件并保存。這個過程不詳細闡述,下一部分會闡述我們的自動化方案。我們先看下拿到 Hprof 文件后人工分析的過程。
瀏覽器的內存分析工具運行的方法如下圖所示。
運行完畢后將得到如下的分析結果文件。
需要重點查看的文件是 suspicion 文件,其內容如下圖所示。
首先從圖中可以看出 NewActivity 的對象泄漏了,該對象在操作過程中新創建出 5 個對象,內存增長了93696字節,內存中該對象的總數量為 13 個。
接著從圖中的調用關系可以分析出,TextManager有一個listeners的數組持有了 NewActivity 的對象。
最后對比源代碼查看輸出結果可以一目了然的看出TextManager是一個單例的對象,而泄露對象應該是注冊了 TextManager 的 ITextChangeListener,沒有取消注冊引起的泄漏。
我相信當測試人員把泄漏對象的根因連同 Bug 一起提交給開發時,開發同事們一定會覺得你很牛 X 。
此外泄露分析過程中還有一種常見情況,就是很多對象泄露是因為同一個原因,如下圖是通過 Finder 對比得到的結果。
從這個圖中可以看出泄漏對象非常多,如果我們逐個對對象進行原因分析的話,將浪費大量的時間,但是實際上這些對象的泄漏都是因為 NewActivity 的泄漏造成的。為了提高我們的分析效率, HprofComparator 對泄漏對象進行了去重處理。
如上圖所示, B 和 C 都為泄露嫌疑,從 B 和 C 的 Callstack 可以看出 B 是 C 的父對象( B 引用 C ),因此只要 B 釋放了, C 也會釋放。這種情況時我們就會將 C 合并到 B ,最終結果輸出 B 。如前面的 suspicion 文件內容中顯示,有92個對象被 duplicate 到了 NewActivity 上。這樣做之后輸出結果會被大量的精簡,需要分析原因的對象數量將會大大減少,節省了許多的時間。
3)關鍵字驅動的自動化方案
在 QQ 瀏覽器項目中一開始還是人工獲取 Hprof 文件,這樣做的測試效率比較低。為了提高測試效率我們也引入了自動化測試,但如何才能讓自動化測試投入產出比比較高呢?
在分析了我們的測試場景和測試執行過程后,我發現內存泄露測試基本上可以分為做操作和獲取 Hprof 文件,而操作又分為點擊、滑動、旋轉屏幕、等待和輸入文字等。整個測試過程中除了需要確保操作是正確的外,并不需要功能的驗證。
基于這些特點,我選擇關鍵字驅動的自動化方案,就是為了以簡便的方式來實現自動化,減少開發和維護成本。
如下圖所示,在測試打開小說書城的場景,需要啟動程序,然后點擊小說入口,然后返回,需要重復打開小說的過程。在腳本中直接省略了打開應用程序的操作, repeat 關鍵字說明后續的步驟是需要重復操作的,而點擊小說入口則僅以“小說”替代。這樣就使測試腳本足夠簡單,任何剛入門的測試人員都可以完成。
在腳本要進行的操作都以關鍵字描述,測試時這些關鍵字都將轉換成控件進行控件查找,或者轉換成坐標直接點擊。
以上的腳本還只是測試數據,我們需要一個測試驅動程序來分析測試腳本,以及執行對應的操作。在 QQ 瀏覽器項目中采用 Python 在實現驅動程序,并結合 Appium 實現自動化測試。驅動程序的執行流程非常簡單,它就負責解析數據文件,然后執行關鍵字對應的操作。腳本的解析如下圖的代碼所示,每一個關鍵字會被處理成對應的命令,并存放到列表里。
以上測試運行過程中還會伴隨著截圖,用于后期分析時確保測試是正確執行的。當測試運行完畢后, hprof 文件將被 Pull 到電腦上,并使用自動分析工具進行泄漏分析。
4)測試運行情況
目前內存泄露測試已經加入到每個版本的常規測試中,每個版本平均能掃描出10+內存泄漏的問題。
手動測試和自動化測試對比情況如下圖所示,內存泄露自動化測試的效率提升主要體現兩個方面:
? 測試效率提升。人工測試 150+ 用例大概需要 5 人日,而現在可以一晚上運行完畢。
? 分析效率提升。人工通過 Finder 進行分析,需要近 5 個人日,而現在僅需要 1 天就可以完成。
通過這樣的方法不僅保證了測試的準確性,也保證了測試的全面性,整體測試效率提升 85% 。
3.后續思考
由于瀏覽器的內存泄漏分析方法與被測試的應用無關 , 后續將考慮實現泄漏分析平臺化 , 這樣可以讓更多的項目快速的應用起來。
目前在瀏覽器項目使用了一種的基于模型的用例生成方法 , 但模型需要人工創建 ,以后 可以嘗試對任意的應用程序自動生成模型并自動創建用例 .
來自: http://www.tuicool.com/articles/ZBbyMra