Android性能測試初體驗

背景

前段時間自己摸索著做了一些Android性能測試,現在告一段落,是時候整理一下筆記了。回顧自己期間學到的東西,順便規劃下后續深入學習的方向。

性能關注點

  • 渲染: 過度繪制、布局冗雜
  • 資源消耗: CPU、內存
  • 功耗: 流量、耗電

今天我們主要關注CPU和內存,其他的留著后面繼續學習。

測試方法

內存和CPU測試主要是為了檢測應用在用戶不同使用強度下消耗手機內存和CPU的情況,如果內存消耗過大會造成手機使用時卡頓,閃退等現象,進而影響用戶體驗,甚至會影響日活數據和用戶留存等情況。因此,應用的內存占用大小也是產品體驗好壞一個重要指標和測試重點。正常情況下,應用不應占用過多的內存資源,且能夠及時釋放內存,保證整個應用內的穩定性和流暢性。根據手機的使用應用頻度和強度不同,可將應用使用強度分為如下幾種狀態:

  1. 空閑狀態:指啟動應用后,不做任何操作或切換到后臺運行的情況稱為空閑狀態。
  2. 中規格狀態:指后臺已經有幾個應用在運行,已經并且消耗了系統的一些資源的情況。
  3. 滿規格狀態:該種情況為應用內高頻率的使用,用戶很少達到,跑monkey時可認為高強度狀態,該種情況常用來測試應用內存泄漏的情況測試時,可根據用戶的操作習慣模擬應用使用頻率和強度等級。

一、使用adb命令

使用adb有很多種獲取cpu和內存的命令,這里我只說我用的順手的,想要了解更多的,動動你的小手自己網上查去吧~

相關結果說明參考:https://blog.csdn.net/wirelessqa/article/details/29187517

查看CPU占用率

  • a. dumpsys獲取實時cpu占用率

    adb shell dumpsys cpuinfo | grep <PackageName>
    

    示例:

    defu@DefuTaideMacBook-Pro $ adb shell dumpsys cpuinfo | egrep 'com.zmsoft.kds: '
    3.4% 32159/com.zmsoft.kds: 2.9% user + 0.4% kernel / faults: 286 minor
    
    # 說明:應用CPU占用率3.4%,其中用戶占用2.9%,內核占用0.4%
    
  • b. top持續監控cpu占用率

    adb shell top -d 0.1 | grep <PackageName>
    

    示例:

    defu@DefuTaideMacBook-Pro $ adb shell top -h
    Usage: top [ -m max_procs ] [ -n iterations ] [ -d delay ] [ -s sort_column ] [ -t ] [ -h ]
        -m num  Maximum number of processes to display. // 最多顯示多少個進程
        -n num  Updates to show before exiting. // 刷新次數
        -d num  Seconds to wait between updates. // 刷新間隔時間(默認5秒)
        -s col  Column to sort by (cpu,vss,rss,thr). // 按哪列排序
        -t      Show threads instead of processes. // 顯示線程信息而不是進程
        -h      Display this help screen. // 顯示幫助文檔
    
    defu@DefuTaideMacBook-Pro $ adb shell top -m 5 -s cpu
    
    User 1%, System 1%, IOW 0%, IRQ 0%
    User 17 + Nice 4 + Sys 14 + Idle 1175 + IOW 0 + IRQ 0 + SIRQ 2 = 1212
    
      PID PR CPU% S  #THR     VSS     RSS PCY UID      Name
      423  2   0% S    79 813500K  54112K  fg system   system_server
    32159  2   0% S   117 897396K 108204K  fg u0_a69   com.zmsoft.kds
    13869  3   0% R     1   1284K    484K     root     top
      101  0   0% S    15  73560K   2996K  fg system   /system/bin/surfaceflinger
      476  2   0% S    23 730980K  34500K  fg u0_a5    com.android.systemui
    
    # 結果說明:
    # CPU占用率: 
    # User    用戶進程 
    # System  系統進程 
    # IOW IO等待時間 
    # IRQ 硬中斷時間 
    
    # CPU使用情況(指一個最小時間片內所占時間,單位jiffies。或者指所占進程數): 
    # User    處于用戶態的運行時間,不包含優先值為負進程 
    # Nice    優先值為負的進程所占用的CPU時間 
    # Sys 處于核心態的運行時間 
    # Idle    除IO等待時間以外的其它等待時間 
    # IOW IO等待時間 
    # IRQ 硬中斷時間 
    # SIRQ    軟中斷時間 
    
    # 進程屬性: 
    # PID 進程在系統中的ID 
    # CPU%    當前瞬時所以使用CPU占用率 
    # S   進程的狀態,其中S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值是負數。 
    # #THR    程序當前所用的線程數 
    # VSS Virtual Set Size 虛擬耗用內存(包含共享庫占用的內存) 
    # RSS Resident Set Size 實際使用物理內存(包含共享庫占用的內存) 
    # PCY OOXX,不知道什么東東 
    # UID 運行當前進程的用戶id 
    # Name    程序名稱android.process.media 
    
  • c. 通過Java代碼獲取

    /**
     * 獲取正在運行時APP的CPU的使用情況,獲取失敗返回0 
     * 返回單位:百分比
     *
     * @return
     */
    public static int getProcessCpuRate(String packageName) {
        int cpuUse = 0;
        try {
            String Result;
            Process processCpuRate = Runtime.getRuntime().exec("adb shell dumpsys cpuinfo | grep " + packageName);
            BufferedReader processCpuRateInput = new BufferedReader(new InputStreamReader(processCpuRate.getInputStream(),"GB2312"));
          
            while ((Result = processCpuRateInput.readLine()) != null) {
                if (Result.length() < 1) {
                    continue;
                } else {
                    String CPUusr = Result.split("%")[0];
                    cpuUse = Integer.valueOf(GetPhoneInfo.getSUM(CPUusr.substring(CPUusr.length() - 3)));
                    return cpuUse;
                }
            }
            processCpuRateInput.close();
        } catch (IOException e) {
            LogUtil.logger().error("Adb 文件不存在!");
            e.printStackTrace();
        }
        return cpuUse;
    }
    

獲取內存使用量

  • a. dumpsys查看內存

      adb shell dumpsys meminfo <PackageName>
    

    示例:

              defu@DefuTaideMacBook-Pro  ~  adb shell dumpsys meminfo com.zmsoft.kds
      Applications Memory Usage (kB):
      Uptime: 2493701465 Realtime: 2493701448
    
      ** MEMINFO in pid 32159 [com.zmsoft.kds] **
                         Pss  Private  Private  Swapped     Heap     Heap     Heap
                       Total    Dirty    Clean    Dirty     Size    Alloc     Free
                      ------   ------   ------   ------   ------   ------   ------
        Native Heap        0        0        0        0    40556    27546      457
        Dalvik Heap    28306    28228        0        0    29852    28886      966
       Dalvik Other     9516     9372        0        0
              Stack       24       24        0        0
             Ashmem        2        0        0        0
          Other dev        9        0        8        0
           .so mmap    11233     6796     3540        0
          .apk mmap      402        0      160        0
          .ttf mmap     1506        0     1176        0
          .dex mmap    15527     1352    11572        0
         Other mmap      234       16      164        0
            Unknown    19409    19400        0        0
              TOTAL    86168    65188    16620        0    70408    56432     1423
    
       Objects
                     Views:     1306         ViewRootImpl:        4
               AppContexts:        7           Activities:        4
                    Assets:        2        AssetManagers:        2
             Local Binders:       32        Proxy Binders:       30
          Death Recipients:        2
           OpenSSL Sockets:        4
    
       SQL
               MEMORY_USED:      851
        PAGECACHE_OVERFLOW:      335          MALLOC_SIZE:       62
    
       DATABASES
            pgsz     dbsz   Lookaside(b)          cache  Dbname
               4      384            459   14908/711/25  /mnt/internal_sd/kds/rcdebug/master/data/db/kdsmaster.db
               4       24            500       26/40/12  /mnt/internal_sd/kds/gadebug/db/kds.db
      
      # 參數含義:
      # VSS – Virtual Set Size 虛擬耗用內存(包含共享庫占用的內存)
      # RSS – Resident Set Size 實際使用物理內存(包含共享庫占用的內存)
      # PSS – Proportional Set Size 實際使用的物理內存(比例分配共享庫占用的內存)
      # USS – Unique Set Size 進程獨自占用的物理內存(不包含共享庫占用的內存)
    
      # // ps:內存占用大小有如下規律:VSS >= RSS >= PSS >= USS 
      # // PSS  Proportional Set Size 實際使用的物理內存(比例分配共享庫占用的內存) 
      # // USS  Unique Set Size 進程獨自占用的物理內存(不包含共享庫占用的內存)
      其中,USS需要設備root后才能獲取,沒有root過的設備獲取PSS即可(PSS獲取方法:adb shell dumpsys meminfo <PackageName> | grep TOTAL)。USS是應用啟動時占用的虛擬內存,殺掉進程即會釋放。
    
  • b. 通過Java代碼獲取內存信息

    /**
     * 獲取APP運行占用的內存,獲取失敗返回0
     * 返回單位:K
     *
     * @return
     */
    public static int getRunMemin(String packageName) {
        int memin = 0;
        try {
            String Result;
            Process p = Runtime.getRuntime().exec("adb shell dumpsys meminfo " + packageName);
    
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), "GB2312"));
            while ((Result = br.readLine()) != null) {
                if (Result.length() < 1) {
                    continue;
                } else {
                    if (Result.contains(AppiumAndroidTest.appPackage)) {
                        memin = Integer.parseInt(GetPhoneInfo.getSUM(Result.split(":")[0]));
                        return memin;
                    }
                }
            }
            br.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            LogUtil.logger().error("Adb 文件不存在!");
            e.printStackTrace();
        }
        return memin;
    }
    

二、使用Android Studio自帶的Android Profiler性能分析工具

相關結果說明參考:http://www.lxweimin.com/p/20a2e7dad7eb

前提條件:
  1. Android系統版本必須5.1.1以上
  2. 設備連接電腦(adb connect連接 or 數據線連接)

Android Studio -> view -> Android Profiler

圖1 - CPU Profiler
圖2 - Memory Profiler
圖3 - Memory Profiler 頂部內存計數圖例
內存計數中的類別如下所示:
  • Java:從 Java 或 Kotlin 代碼分配的對象內存。
  • Native:從 C 或 C++ 代碼分配的對象內存。
  • Graphics:圖形緩沖區隊列向屏幕顯示像素(包括 GL 表面、GL 紋理等等)所使用的內存。 (請注意,這是與 CPU 共享的內存,不是 GPU 專用內存。)
  • Stack: 您的應用中的原生堆棧和 Java 堆棧使用的內存。 這通常與您的應用運行多少線程有關。
  • Code:您的應用用于處理代碼和資源(如 dex 字節碼、已優化或已編譯的 dex 碼、.so 庫和字體)的內存。
  • Other:您的應用使用的系統不確定如何分類的內存。
  • Allocated:您的應用分配的 Java/Kotlin 對象數。 它沒有計入 C 或 C++ 中分配的對象。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,250評論 6 530
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,923評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,041評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,475評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,253評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,801評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,882評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,023評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,530評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,494評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,639評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,177評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,890評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,289評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,552評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,242評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,626評論 2 370