1. 程式人生 > >Android客戶端效能測試—記憶體(一)

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

:13004

                    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再用字串擷取方式獲取記憶體,可對其資料進行返回列印,實現監控。

傳入引數為:應用包名,這個不可變。

  1. package com.hss.performanceTest;

  2. /**

  3. * from hss

  4. * data:2017/9/8

  5. * project:getMemory

  6. */

  7. import java.io.BufferedReader;

  8. import java.io.IOException;

  9. import java.io.InputStreamReader;

  10. public class getMemory {

  11. public static String GetMemory(String packageName) throws IOException, InterruptedException {

  12. String str3=null;

  13. Runtime runtime = Runtime.getRuntime();

  14. Process proc = runtime.exec("adb shell dumpsys meminfo "+packageName);

  15. try {

  16. if (proc.waitFor() != 0) {

  17. System.err.println("exit value = " + proc.exitValue());

  18. }

  19. BufferedReader in = new BufferedReader(new InputStreamReader(

  20. proc.getInputStream()));

  21. StringBuffer stringBuffer = new StringBuffer();

  22. String line = null;

  23. while ((line = in.readLine()) != null) {

  24. stringBuffer.append(line+" ");

  25. }

  26. String str1=stringBuffer.toString();

  27. String str2=str1.substring(str1.indexOf("Objects")-60,str1.indexOf("Objects"));

  28. str3=str2.substring(0,10);

  29. str3.trim();

  30. } catch (InterruptedException e) {

  31. System.err.println(e);

  32. }finally{

  33. try {

  34. proc.destroy();

  35. } catch (Exception e2) {

  36. }

  37. }

  38. return str3 ;

  39. }

  40. public static void main(String args[]) {

  41. System.out.println("開始執行...");

  42. try {

  43. String resurt = getMemory.GetMemory("com.hundsun.stockwinner.sxzq");

  44. System.out.println("山西證券的記憶體:"+resurt);

  45. } catch (IOException e) {

  46. // TODO Auto-generated catch block

  47. e.printStackTrace();

  48. } catch (InterruptedException e) {

  49. // TODO Auto-generated catch block

  50. e.printStackTrace();

  51. }

  52. }

  53. }


執行截圖: