1. 程式人生 > >使用 adb shell 抓取 Android 效能資料

使用 adb shell 抓取 Android 效能資料

轉載地址:https://testerhome.com/topics/3849

前段時間在看Android客戶端效能測試,處於興趣寫了個性能資料抓取的外掛,可以抓取的資料有app啟動時間、cpu、pss、流量上下行、流暢度等。

關於記憶體要說一下為什麼只抓取pss,因為沒有root的情況下無法獲取到uss,pss是最有參考價值的(程序佔用記憶體+按比例分配共享庫佔用的記憶體)

流量抓取方式也略有不同,前一種方法獲取tcp流量,而且在有的裝置上無法獲取到資料,無法做到普適性:

  • 改之前:
adb -s #udid# shell cat /proc/uid_stat/#uid#/tcp_rcv
adb -s #udid# shell cat /proc/uid_stat/#uid#/tcp_snd
  • 改之後:
adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{tx_bytes+=$6}END{print '$(date +%Y%m%d%H%M%S)',tx_bytes}
adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{tx_bytes+=$8}END{print '$(date +%Y%m%d%H%M%S)',tx_bytes}

流暢度閾值的界定:按官網的建議每秒小於60幀就能感覺到不流暢,也就是說每幀的閾值=1000/60 =16ms

app啟動時間獲取原理:

  • 獲取logcat日誌:
adb -s $1 shell logcat -v time -b events > output/$1/latest/logcat_$1.txt &
  • 根據起始關鍵字和結束關鍵字過濾時間戳:
handlLogcat = new Thread(new CmdThread("./shell/appLanchTimeClient.sh " + udid + " " + beginKeywords + " " + endKeywords), "handlLogcat_" + udid);

計算時間差:

startTime = CmdInvoke.run("tail -n 1 output/"
+ udid + "/latest/start_" + udid + ".txt |awk '{print $2}'"); endTime = CmdInvoke.run("tail -n 1 output/" + udid + "/latest/end_" + udid + ".txt |awk '{print $2}'"); lantchTime = DateUtil.getDifTwoTime(DateUtil.parsehmsS(endTime), DateUtil.parsehmsS(startTime), "S");

獲取裝置的一些臨界值

heapgrowthlimit=`adb -s $udid shell getprop dalvik.vm.heapgrowthlimit
heapstartsize=`adb -s $udid shell getprop dalvik.vm.heapstartsize`
heapsize=`adb -s $udid shell getprop dalvik.vm.heapsize`
echo "#單個應用程式最大記憶體限制" > output/$udid/devMemLimit.txt
echo "heapgrowthlimit="$heapgrowthlimit >> output/$udid/devMemLimit.txt
echo "#單個java虛擬機器最大的記憶體限制" >> output/$udid/devMemLimit.txt
echo "heapsize="$heapsize >> output/$udid/devMemLimit.txt
echo "#每幀重新整理耗時閾值(ms)" >> output/$udid/devMemLimit.txt
#60FPS<==>每幀<=16ms FPS=1000/(Draw+Process+Execute) 
#開啟android手機 設定->開發者選項->GPU呈現模式分析
echo "gfxinfo=16.00" >> output/$udid/devMemLimit.txt
命令模板
public class CmdTemplate {
    public static String PID = "adb -s #udid# shell dumpsys meminfo #packageName#|grep pid|awk '{print $5}'";
    public static String UID = "adb -s #udid# shell dumpsys package #packageName#|grep packageSetting|cut -d \"/\" -f2|cut -d \"}\" -f1";

        /**實時抓取**/
    // TIMESTAMP(yyyymmddHHMMSS) CPU(%) PID/PACKAGE
    public static String CPU_USAGE = "adb -s #udid# shell dumpsys cpuinfo|grep #filter#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$2}'|grep #pid#";

    // TIMESTAMP(yyyymmddHHMMSS) PSS(KB) PACKAGE
    public static String PSS = "adb -s #udid# shell dumpsys meminfo|awk '/process:/,/adjustment:/{if(i>1)print x;x=$0;i++}'|grep #filter#|grep #pid#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$3}'";

    // TIMESTAMP(yyyymmddHHMMSS) RX_BYTES(BYTE)
    public static String RX_BYTES = "adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{rx_bytes+=$6}END{print '$(date +%Y%m%d%H%M%S)',rx_bytes}'";

    // TIMESTAMP(yyyymmddHHMMSS) TX_BYTES(BYTE)
    public static String TX_BYTES = "adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{tx_bytes+=$8}END{print '$(date +%Y%m%d%H%M%S)',tx_bytes}'";

        /**非同步抓取**/
    // TIMESTAMP(yyyymmddHHMMSS) PID VSS(KB) RSS(KB) PACKAGE
    public static String SAVE_TOP_INFO = "adb -s #udid# shell top -n 1 -d 0|grep #filter#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$6,$7,$10}' >> output/#udid#/latest/top_#udid#.txt";

    // TIMESTAMP(yyyymmddHHMMSS) CPU(%) PID/PACKAGE
    public static String SAVE_CPU_INFO = "adb -s #udid# shell dumpsys cpuinfo|grep #filter#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$2}' >> output/#udid#/latest/cpu_#udid#.txt";

    // TIMESTAMP(yyyymmddHHMMSS) PSS(KB) PACKAGE
    public static String SAVE_PSS_INFO = "adb -s #udid# shell dumpsys meminfo|awk '/process:/,/adjustment:/{if(i>1)print x;x=$0;i++}'|grep #filter#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$3}' >> output/#udid#/latest/pss_#udid#.txt";

    // TIMESTAMP(yyyymmddHHMMSS) RX_BYTES(BYTE) TX_BYTES(BYTE)
    public static String SAVE_TRAFFIC_INFO = "adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{rx_bytes+=$6}{tx_bytes+=$8}END{print '$(date +%Y%m%d%H%M%S)',rx_bytes,tx_bytes}' >> output/#udid#/latest/traffic_#udid#.txt";

    // Draw(MS) Process(MS) Execute(MS)
    public static String SAVE_GFX_INFO = "adb -s #udid# shell dumpsys gfxinfo #packageName#|awk '/Execute/,/hierarchy/{if(i>1)print x;x=$0;i++}'|sed /^[[:space:]]*$/d|awk '{if(length($0)==16)print $1,$2,$3}' >> output/#udid#/latest/gfxinfo_#udid#.txt";
}

支援實時抓取資料和非同步抓取資料,非同步抓取每個抓取型別會分配一個執行緒,非同步抓取的資料以檔案形式持久化到本地。

pss抓取內容
20151201163741 41414 com.yzt
20151201163741 22044 com.yzt:remote
20151201163741 21048 comyzt:pushservice
20151201163741 19309 com.yzt:push
20151201163747 48010 com.yzt
20151201163747 22047 com.yzt:remote
20151201163747 21132 com.yzt:pushservice
20151201163747 19333 com.yzt:push

cpu抓取內容
20151201163739 0.8% 9819/com.yzt:remote:
20151201163739 0% 9699/com.yzt:
20151201163743 5.2% 9699/com.yzt:
20151201163743 1% 9819/com.yzt:remote:
20151201163743 0% 14177/com.yzt:pushservice:

流量抓取內容
20151201163740 1119317 1313028
20151201163743 1119317 1313028
20151201163746 1429836 1328958
20151201163749 1509060 1337427
20151201163752 2525902 1381403

每幀耗時抓取內容
1.30 1.25 0.53
0.63 0.62 1.64
0.24 0.51 0.44
0.25 1.76 0.40
0.25 1.55 0.43
0.25 0.53 0.37
0.49 1.51 2.12
0.45 0.67 0.27
0.43 0.71 2.83
0.43 0.76 3.04

報表展示:



注:圖表展現工具可以使用 【highchart】