Android客戶端效能測試—記憶體(一)
前言:
1.該內容為APP應用客戶端的效能測試,未涉及後臺,所以並非針對API或資料介面
2.測試的目標項:資源消耗、記憶體洩露、電量功耗、響應時間
3.客戶端的效能指標:記憶體、CPU、流量
4.本系列主要是講述 如何獲取安卓APP應用的效能指標,並簡單分析,定位問題
一、檢視 記憶體 指標:
準備工作:
(1).進入裝有測試APP手機的 “開發人員選項” 並開啟“USB除錯模式”
(2).使用資料線將手機裝置與電腦裝置連線,可裝PP助手進行接入
(3).手機開啟待測APP,即開啟程序
1.命令列檢視記憶體資料:
(1).開啟cmd
(2). 獲取裝置列表:輸入 adb devices(預先安裝adb驅動、若報錯,拔掉重新連線手機)
(3).進入該裝置的shell環境:輸入:adb -s C7R6T16722004661 shell (若只有一臺裝置,可直接 adb shell ,多臺必須加裝置序列號C7R6T16722004661)
(4).查詢程序:輸入ps (模糊查詢) 尋找對應待測應用包名,並記錄下其的pid(程序ID):30017,
若知道明確的包名,可直接準確查詢 ps |grep com.hundsun.stockwinner.grzq
(5).查詢記憶體資訊:
可通過兩種方式獲取:
a.通過 “ dumpsys meminfo 包名/pid ” 命令獲取,輸入:dumpsys meminfo 30017
Pss Total :實際使用的實體記憶體
private dirty:私有駐留記憶體
Heap Size: 佔用總記憶體(Heap 堆)(擴充套件:程序記憶體空間是虛擬記憶體,區分於物理記憶體,程序無法直接操作實體記憶體RAM。必要時,作業系統對其進行對映,使程序能應用到實體記憶體)
Heap Alloc: 分配記憶體
Heap Free: 空閒記憶體
native process和java process佔據記憶體的大小(擴充套件:c++申請的記憶體為native process,java申請的記憶體:java process)
記憶體大小:native process
dalvik process:10448
注:因為Android系統對dalvik的vm heapsize作了硬性限制,當java程序申請的java空間超過閾值時,就會丟擲OOM異常(這個閾值可以是48M、24M、16M等,視機型而定)
檢視單個應用最大記憶體限制,輸入命令:getprop|grep heapgrowthlimit 得到結果該機型為192M。dalvik process 超過就會拋OOM異常
b.可直接通過:procrank 。
手機中的sh是經過精簡過的,有些手機可能沒有 procrank 命令,可以使用genymotion模擬器,或是自己安裝procrank命令。
(我也沒這個命令,沒有裝好,這部分內容未操作,為網路直接獲取)
VSS- Virtual Set Size 虛擬耗用記憶體(包含共享庫佔用的記憶體)——是單個程序全部可訪問的地址空間
RSS- Resident Set Size 實際使用實體記憶體(包含共享庫佔用的記憶體)——單個程序實際佔用的記憶體大小,不是精確描述
PSS- Proportional Set Size 實際使用的實體記憶體(比例分配共享庫佔用的記憶體)——對於系統中的整體記憶體使用是一個很好的描述
USS- Unique Set Size 程序獨自佔用的實體記憶體(不包含共享庫佔用的記憶體)——單個程序的全部私有記憶體大小,亦即全部被該程序獨佔的記憶體大小。
一般來說記憶體佔用大小有如下規律:VSS >= RSS >= PSS >= USS。
USS 是針對某個程序開始有可疑記憶體洩露的情況,進行檢測的最佳數字
2.程式碼獲取記憶體資料:
java呼叫Adb shell dumpsys meminfo再用字串擷取方式獲取記憶體,可對其資料進行返回列印,實現監控。
傳入引數為:應用包名,這個不可變。
-
package com.hss.performanceTest;
-
/**
-
* from hss
-
* data:2017/9/8
-
* project:getMemory
-
*/
-
import java.io.BufferedReader;
-
import java.io.IOException;
-
import java.io.InputStreamReader;
-
public class getMemory {
-
public static String GetMemory(String packageName) throws IOException, InterruptedException {
-
String str3=null;
-
Runtime runtime = Runtime.getRuntime();
-
Process proc = runtime.exec("adb shell dumpsys meminfo "+packageName);
-
try {
-
if (proc.waitFor() != 0) {
-
System.err.println("exit value = " + proc.exitValue());
-
}
-
BufferedReader in = new BufferedReader(new InputStreamReader(
-
proc.getInputStream()));
-
StringBuffer stringBuffer = new StringBuffer();
-
String line = null;
-
while ((line = in.readLine()) != null) {
-
stringBuffer.append(line+" ");
-
}
-
String str1=stringBuffer.toString();
-
String str2=str1.substring(str1.indexOf("Objects")-60,str1.indexOf("Objects"));
-
str3=str2.substring(0,10);
-
str3.trim();
-
} catch (InterruptedException e) {
-
System.err.println(e);
-
}finally{
-
try {
-
proc.destroy();
-
} catch (Exception e2) {
-
}
-
}
-
return str3 ;
-
}
-
public static void main(String args[]) {
-
System.out.println("開始執行...");
-
try {
-
String resurt = getMemory.GetMemory("com.hundsun.stockwinner.sxzq");
-
System.out.println("山西證券的記憶體:"+resurt);
-
} catch (IOException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
} catch (InterruptedException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
}
-
}
執行截圖: