編輯:關於Android編程
在進行Android內存洩露分析時,面對成千上萬個對象,你是否藍瘦,香菇?作為測試人員你在進行內存洩露測試之後,是否有勇氣告訴開發同事程序已經沒有內存洩露,可以放心發布了?
眾所周知,內存洩露測試難點在於准確的定位出洩露的對象。現在小哥有種方法通過一條命令就高效全面的得到Android程序內存洩露對象,讓你不再藍瘦,香菇!
目前我知道的幾種常用的Android內存洩漏方案主要有MAT、騰訊內部開發的Finder、LeakCanary以及浏覽器目前使用的方法。
幾種方法,我們通過以下的幾個緯度進行對比。
最原始的Java內存洩露分析方式,是通過MAT將測試操作前後的Hprof文件進行對比,然後根據對比結果來嘗試識別出洩露對象,這種方法效率比較低。
如果使用騰訊的Finder工具來進行洩露分析,效率將會提高很多,但還是手動執行,也存在時間浪費的問題。
也可以使用LeakCanary或者騰訊自研的LeakInspector來測試,由於這兩個工具是自動分析,效率會更加高效。但需要修改代碼,把工具的SDK引入到工程中。此外針對不退出Activity的測試場景,不能很好的處理。
而我們的分析方法,一條命令就可以完成分析,並輸出詳細的洩露對象,以及調用關系。
從前面的表中可以看LeakCanary各方面都挺優秀,但是我們為什麼沒有使用它呢?這是因為QQ浏覽器很多場景都是在MainActivity中進行的,比如打開網頁,此時MainActivity並不會Destroy,直接使用LeakCanary無法進行洩漏分析,因此我們才考慮自己實現一個分析工具。
在QQ浏覽器項目中,使用的分析工具叫做HprofComparator,這是我們自己開發的一個Eclipse Application,其原理與Finder的對比原理一致,但是加入了洩露分析的策略,可以通過命令行直接運行,更加的高效。
做內存洩漏測試一定要全面的測試才敢通知項目組放心發布,目前QQ浏覽器選擇對所有的畫面進行洩漏排查。
內存出現洩漏的前提條件一定是有新的內存分配,所以測試場景會選擇有新對象創建的場景,並結合用戶的使用場景和頻率來確定優先級。測試場景主要有以下三種情況:
? 新畫面打開 由於新的畫面打開,就會創建新的Activity,並有許多其他對象被創建。 ? 畫面旋轉 當屏幕旋轉時,Orientation設置發生了改變,當前顯示的Activity會被重新創建。 ? 滑動屏幕 滑動屏幕會使屏幕中顯示的對象(比如浏覽器小說閱讀內容)創建。
測試方法就是重復運行以上選擇的場景,將整個測試過程分幾個階段獲取到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 上。這樣做之後輸出結果會被大量的精簡,需要分析原因的對象數量將會大大減少,節省了許多的時間。
在QQ浏覽器項目中一開始還是人工獲取Hprof文件,這樣做的測試效率比較低。為了提高測試效率我們也引入了自動化測試,但如何才能讓自動化測試投入產出比比較高呢?
在分析了我們的測試場景和測試執行過程後,我發現內存洩露測試基本上可以分為做操作和獲取Hprof文件,而操作又分為點擊、滑動、旋轉屏幕、等待和輸入文字等。整個測試過程中除了需要確保操作是正確的外,並不需要功能的驗證。
基於這些特點,我選擇關鍵字驅動的自動化方案,就是為了以簡便的方式來實現自動化,減少開發和維護成本。
如下圖所示,在測試打開小說書城的場景,需要啟動程序,然後點擊小說入口,然後返回,需要重復打開小說的過程。在腳本中直接省略了打開應用程序的操作,repeat關鍵字說明後續的步驟是需要重復操作的,而點擊小說入口則僅以“小說”替代。這樣就使測試腳本足夠簡單,任何剛入門的測試人員都可以完成。
在腳本要進行的操作都以關鍵字描述,測試時這些關鍵字都將轉換成控件進行控件查找,或者轉換成坐標直接點擊。
以上的腳本還只是測試數據,我們需要一個測試驅動程序來分析測試腳本,以及執行對應的操作。在QQ浏覽器項目中采用Python在實現驅動程序,並結合Appium實現自動化測試。驅動程序的執行流程非常簡單,它就負責解析數據文件,然後執行關鍵字對應的操作。腳本的解析如下圖的代碼所示,每一個關鍵字會被處理成對應的命令,並存放到列表裡。
以上測試運行過程中還會伴隨著截圖,用於後期分析時確保測試是正確執行的。當測試運行完畢後,hprof文件將被Pull到電腦上,並使用自動分析工具進行洩漏分析。
目前內存洩露測試已經加入到每個版本的常規測試中,每個版本平均能掃描出10+內存洩漏的問題。
手動測試和自動化測試對比情況如下圖所示,內存洩露自動化測試的效率提升主要體現兩個方面:
? 測試效率提升。人工測試150+用例大概需要5人日,而現在可以一晚上運行完畢。 ? 分析效率提升。人工通過Finder進行分析,需要近5個人日,而現在僅需要1天就可以完成。
通過這樣的方法不僅保證了測試的准確性,也保證了測試的全面性,整體測試效率提升85%。
由於浏覽器的內存洩漏分析方法與被測試的應用無關,後續將考慮實現洩漏分析平台化,這樣可以讓更多的項目快速的應用起來.
目前在浏覽器項目使用了一種的基於模型的用例生成方法,但模型需要人工創建,以後可以嘗試對任意的應用程序自動生成模型並自動創建用例.
首先配置一個布局: 然後在activity中把發短信的代碼寫出來: package com.ydl.smssender;i
本文基於Android 4.2.2從進程/文件的角度審視Android Camera子系統。 AndroidCamera子系統的整體架構分成客戶端(Client)和
面試中經常會問到內存優化,我們在開發過程中也多少會遇到OOM的問題,根據大牛們的博客,記錄下我的學習思路一、為何會OOM?1. 一直以來Andorid手機的內存都比iPh
主要實現辦法:動態加載各級下拉值的適配器在監聽本級下拉框,當本級下拉框的選中值改變時,隨之修改下級的適配器的綁定值 &