1. 程式人生 > >App效能測試中的幾個重要概念

App效能測試中的幾個重要概念

我們在使用各種 App 的時候基本會關注到:這款軟體挺耗流量的?執行起來裝置掉電有點快嘛?切換頁面的時候還會有卡頓等現象?如果遇到有這些問題的 App 我們基本會將它請出我們的

我們在使用各種 App 的時候基本會關注到:這款軟體挺耗流量的?執行起來裝置掉電有點快嘛?切換頁面的時候還會有卡頓等現象?如果遇到有這些問題的 App 我們基本會將它請出我們的愛機。由此可見軟體是否受歡迎除了提供必要的功能外,流暢性、流量/電池消耗也是很重要的指標。

今天就來從我們測試人員的角度,談一談 App 驗收測試過程中需要關注到一些指標專案:

  • 記憶體佔用

  • CPU 佔用

  • 流量耗用

  • 電量耗用

  • 啟動時間

因為最近就著騰訊 TMQ 團隊出版的《移動 App 效能評測與優化》這本書在看 App 效能測試這一塊的東西,看著看著發現有些名詞或者概念不是很明白,所以在看這塊東西的時候,還要一邊去查詢一些其他的點,現在將這些點記錄下來,也算是一篇讀書筆記了吧,下面針對每一個方面的一些重要知識點進行了整理。

一. 記憶體

1. 記憶體洩漏

說到記憶體方面,最經典的記憶體問題當數記憶體洩漏。百度上對記憶體洩漏的定義是這樣的:記憶體洩漏(Memory Leak)是指程式中己動態分配的堆記憶體由於某種原因程式未釋放或無法釋放,造成系統記憶體的浪費,導致程式執行速度減慢甚至系統崩潰等嚴重後果。通俗點講,在大部分應用中,會有一類功能是需要載入附加資源的,比如顯示從網路

下載的文字或圖片。這類功能往往需要在記憶體中存放要使用的資源物件,退出該功能後,就需要將這些資源物件清空。如果忘了清理,或者是程式碼原因造成的清理無效,就會形成記憶體洩漏。

2. 垃圾回收

說到了記憶體洩漏,又不得不提到垃圾回收(Garbage Collector,簡稱 GC),記憶體中的垃圾,主要指的是記憶體中已無效但又無法自動釋放的空間,除非是重啟系統不然永遠也不會還給作業系統。這樣以來,時間久了當程式執行的時候就會產生很多垃圾,一方面浪費了不少記憶體空間,另一方面如果同一個記憶體地址被刪除兩次的話,程式就會不穩定,甚至奔潰。

在 Java 程式執行過程中,一個垃圾回收器會不定時地被喚起檢查是否有不再被使用的物件,並釋放它們佔用的記憶體空間。但垃圾回收器的回收是隨機的,可能在程式的執行的過程中,一次也沒有啟動,也可能啟動很多次,它並不會因為程式一產生垃圾,就馬上被喚起而自動回收垃圾。所以垃圾回收也並不能完全避免記憶體洩漏的問題。

另一方面,垃圾回收也會給系統資源帶來額外的負擔和時空開銷。它被啟動的機率越小,帶來的負擔的機率就越小。

3. 記憶體指標

記憶體指標有 VSS、RSS、PSS、USS,他們的含義分別是:

VSS:Virtual Set Size 虛擬耗用記憶體(包含共享庫佔用的記憶體)

RSS:Resident Set Size 實際使用實體記憶體(包含共享庫佔用的記憶體)

PSS:Proportional Set Size 實際使用的實體記憶體(按比例分配共享庫佔用的記憶體)

USS:Unique Set Size 程序獨自佔用的實體記憶體(不包含共享庫佔用的記憶體)

一般來說記憶體佔用大小有如下規律:VSS >= RSS >= PSS >= USS,一般測試中關注的比較多的是 PSS 這個指標。

4. 監控與分析工具

以下是幾種常見的記憶體分析工具,具體使用方法這裡就不詳述了。

4.1 Memory Monitor

該工具位於 Android Monitor 下面,Android Monitor 是 Android Studio 自帶的一個強大的效能分析工具,裡面一共包含 5 個模組:Logcat、Memory、CPU、Network 及 GPU。

Memory Monitor 可以實時檢視 App 的記憶體分配情況,判斷 App 是否由於 GC 操作造成卡頓以及判斷 App 的 Crash 是否是因為超出了記憶體。

4.2 Heap Viewer

該記憶體檢測工具位於 DDMS 下面,在 Android Studio 裡面可以通過 Tools-Android-Android Device Monitor 開啟,Heap Viewer 可以實時檢視 App 分配的記憶體大小和空閒記憶體大小,並且發現 Memory Leaks。

4.3 MAT

MAT(Memory Analyzer Tool),是一個被老生常談的 Android 記憶體分析工具,它可以清楚的獲知整體記憶體使用情況。雖然是 Eclipse 的工具,但也可以單獨執行,不需要安裝 Eclipse。

二. CPU

1. 時間片

時間片即 CPU 分配給各個程式的時間,每個執行緒被分配一個時間段,稱作它的時間片,即該程序允許執行的時間,使各個程式從表面上看是同時進行的。

2. Jiffies

2.1 Jiffies的概念

要講 Jiffies 需要先提到這兩個概念:HZ 和 Tick

HZ:Linux 核心每隔固定週期會發出 timer interrupt (IRQ 0),HZ 是用來定義每一秒有幾次 timer interrupts。例如 HZ 為 1000,就代表每秒有 1000 次 timer interrupts。
Tick:HZ 的倒數,Tick = 1/HZ,即 timer interrupt 每發生一次中斷的時間。如 HZ 為 250 時,tick 為 4 毫秒(millisecond)。

而 Jiffies 為 Linux 核心變數,是一個 unsigned long 型別的變數,被用來記錄系統自開機以來,已經過了多少 tick。每發生一次 timer interrupt,Jiffies 變數會被加 1。

2.2 檢視 Jiffies 的方法

Linux 下使用命令 cat /proc/stat ,檢視具體整機的 Jiffies,如圖:

Linux 下使用命令 cat /proc/<程序id>/stat ,檢視具體某個程序的 Jiffies:

3. CPU 使用率

在 Linux 系統下,CPU 利用率分為使用者態、系統態和空閒態,他們分別代表的含義為:使用者態表示 CPU 處於使用者態執行的時間,系統態表示系統核心執行的時間,空閒態表示空閒系統程序執行的時間。

而一個 App 的 CPU 使用率 = CPU 執行非系統空閒程序時間 / CPU 總的執行時間,也可以表示為 App 使用者態 Jiffies + App 系統態 Jiffies / 手機總 Jiffies。

4. CPU 過高會帶來的影響

可能會使整個手機無法響應,整體效能降低,引起 ANR,導致手機更耗電,降低使用者體驗等。

三. 流量

1. 定義

我們的手機通過運營商的網路訪問 Internet,運營商替我們的手機轉發資料報文,資料報文的總大小(位元組數)即流量,資料報文是包含手機上下行的報文。

2. 常用流量測試方法

2.1 抓包測試法

主要是利用工具 Tcpdump 抓包,匯出 pcap 檔案,再在 wireshark 中開啟進行分析。

2.2 統計測試法

2.2.1 讀取 linux 流量統計檔案

利用 Android 自身提供的 TCP 收發長度的統計功能,獲取 App 的 tcp_snd 和 tcp_rcv 的值,測試一段時間後再分別統計一次,用 tcp_snd

兩者的差值得到傳送流量,用 tcp_rcv 兩者的差值得到接受流量。

2.2.2 利用 Android 流量統計 API

  • TrafficStats

Android 2.2 版本開始加入 android.net.TrafficStats 類來實現對流量統計的操作。

部分方法如下:

static long getMobileRxBytes() //獲取通過移動資料網路收到的位元組總數 
static long getMobileTxBytes() //通過移動資料網傳送的總位元組數 
static long getTotalRxBytes() //獲取裝置總的接收位元組數 
static long getTotalTxBytes() //獲取裝置總的傳送位元組數 
static long getUidRxBytes(int uid) //獲取指定uid的接收位元組數 
static long getUidTxBytes(int uid) //獲取指定uid的傳送位元組數
  • NetworkStatsManager

Android 6.0 版本開始,為了打破了原本 TrafficStats 類的查詢限制,官方又提供了 NetworkStatsManager 類,可以獲取更精準的網路歷史資料,也不再是裝置重啟以來的資料。部分方法如下:

NetworkStats.Bucket querySummaryForDevice(int networkType, String subscriberId, long startTime, long endTime) // 查詢指定網路型別在某時間間隔內的總的流量統計資訊
 NetworkStats queryDetailsForUid(int networkType, String subscriberId, long startTime, long endTime, int uid) // 查詢某uid在指定網路型別和時間間隔內的流量統計資訊
 NetworkStats queryDetails(int networkType, String subscriberId, long startTime, long endTime) // 查詢指定網路型別在某時間間隔內的詳細的流量統計資訊(包括每個uid)

四. 電量

1.耗電場景

  • 定位,尤其是呼叫 GPS 定位。

  • 網路傳輸,尤其是非 Wifi 環境。

  • 螢幕亮度

  • CPU 頻率

  • 記憶體排程頻度

  • wake_locker 時間和次數

  • 其他感測器

2.測試方法

2.1 通過系統檔案獲取電量記錄

使用命令 adb shell dumpsys batterystats> batterystats.txt   可以打印出詳細的耗電相關資訊並儲存統計的電量資訊到 batterystats.txt 這個檔案裡。

2.2 通過匯入 batterystats.txt 到 Google 開源工具 battery historian 進行分析

因為這個工具是 Go 語言開發,所以需要預裝Go語言開發環境,當然如果你不想配置Go語言環境,官方還提供了一種更方便的方案,通過安裝 docker 環境來使用這個工具。具體這個工具的配置安裝和具體使用方法以及引數的代表含義,我會單獨再寫一篇文章記錄,先拋磚引玉放一張這個工具的執行截圖。

3.優化方法

3.1 CPU 時間片

當應用退到後臺執行時,儘量減少應用的主動執行,當檢測到 CPU 時間片消耗異常時,深入執行緒進行分析。

3.2 wake lock

前臺執行時不要註冊 wake lock。

後臺執行時,在保證業務需要的前提下,應儘量減少註冊 wake lock。

降低對系統的喚醒頻率, 使用 partial wake lock 代替 wake lock。

3.3 感測器

合理設定 GPS 的使用時長和使用頻率。

3.4 雲省電策略

考慮到使用者使用場景的多樣性,導致很難定位使用者異常耗電的根源,所以為了更深一層弄清楚這些問題,可以考慮定期上報灰度使用者手機電量資料的方式來分析問題。

五. 啟動時間

可使用命令 adb shell am start -W packagename/activity   檢視 App 啟動耗時,查看了一下我們自己的 App Android 版本的啟動耗時如下:

註釋:

WaitTime:總的耗時,包括前一個應用 Activity pause 的時間和新應用啟動的時間

ThisTime:一連串啟動 Activity 的最後一個 Activity 的啟動耗時

TotalTime:新應用啟動的耗時,包括新程序的啟動和 Activity 的啟動,但不包括前一個應用 Activity pause 的耗時

六. 總結

App效能問題會直接影響產品體驗:耗流量、掉電快、卡頓、崩潰等現象會給使用者造成不良的體驗和印象,不利於產品的活躍及使用者留存。許多經驗豐富的程式設計師也會經常忽視這些不起眼的效能問題,因此作為測試人員,在版本釋出前及早關注並發現上述效能問題就顯得尤其重要。但真正做起App效能測試才發現這條路並不容易走,抓取記憶體、CPU 等一些專案的指標容易,但對一些資料的敏感度和處理方式都是要靠經驗的慢慢積累。總之,效能測試算是一項比較繁瑣的工作,但難者不易,易者不難,希望已經行走在這條路上的或者準備踏上這條路的同行都能不斷提高自身素養,堅持到底。

最後跟大家推薦一個測試學習群:747981058,裡面大牛已經為我們整理好了許多的學習資料,有自動化,介面,效能等等的學習資料!