Android性能測試(內存、cpu、fps、流量、GPU、電量)——adb篇

adb 常用命令

  1. 獲取連接設備號:adb devices
  2. 列出設備所有已安裝的包名 (不需root權限)
    adb shell “pm list packages”,可以加上grep 進行篩選(windows系統(tǒng)使用findstr /i "xxxx" 或者 find)

3)查看進程列表:adb shell "ps",同時也能獲取到應用的UID,方式如下(不需root權限):


u0_a開頭的都是Android的應用進程,Android的應用的UID是從10000開始,到19999結束,可以在Process.java中查看到(FIRST_APPLICATION_UID和LAST_APPLICATION_UID),u0_a后面的數字就是該應用的UID值減去FIRST_APPLICATION_UID所得的值,所以,對于截圖這個應用進程,它是u0_a155,按前面的規(guī)制,它的UID就是155 + FIRST_APPLICATION_UID = 10155。

內存說明

VSS - Virtual Set Size 虛擬耗用內存(包含共享庫占用的內存)
RSS - Resident Set Size 實際使用物理內存(包含共享庫占用的內存)
PSS - Proportional Set Size 實際使用的物理內存(比例分配共享庫占用的內存)
USS - Unique Set Size 進程獨自占用的物理內存(不包含共享庫占用的內存)
一般來說內存占用大小有如下規(guī)律:VSS >= RSS >= PSS >= USS

adb 查看單個內存占用量 (均不需要root權限)

  1. 單個應用的最大內存限制

    adb shell "getprop | grep heapgrowthlimit"
  2. 應用啟動后分配的初始內存

    adb shell "getprop|grep dalvik.vm.heapstartsize"
  3. 單個java虛擬機的最大內存限制

    adb shell "getprop|grep dalvik.vm.heapsize"

adb內存數據采集

使用 adb shell "dumpsys meminfo -s <pakagename | pid>"命令,輸出結果分以下4部分:

  1. process 以進程的PSS從大到小依次排序顯示,每行顯示一個進程;
  2. OOM adjustment 分別顯示每類的進程情況
  3. category 以Dalvik/Native/.art mmap/.dex map等劃分的各類進程的總PSS情況
  4. total 總內存、剩余內存、可用內存、其他內存

執(zhí)行結果如下圖,重點取該應用的TOTAL 對應的內存占用大小(KB)

PS:在apk內調用運行獲取其他app的內存數據則需要root權限

adb fps(每秒幀數,計算流暢度)數據采集

adb命令:adb shell dumpsys gfxinfo <package | pid>

前提:開發(fā)者選項=>GPU呈現模式分析確保打開=>在adb shell dumpsys gfxinfo中or 在屏幕上顯示為線型圖
方法僅適用于Android原生應用,不適用于游戲

正常情況下幀率應該在16.67ms左右,1秒60幀,執(zhí)行結果如下:


gfxinfo

詳細計算方法如下:

  1. 首先獲取執(zhí)行一次命令打印出來的結果,重點關注Draw Prepare Process Execute 行下面的數據
    Draw:是消耗在構建java顯示列表DisplayList的時間。說白了就是執(zhí)行每一個View的onDraw方法,創(chuàng)建或者更新每一個View的DisplayList對象的時間。
    Process:表示是消耗在Android的2D渲染器執(zhí)行顯示列表的時間,view越多,要執(zhí)行的繪圖命令就越多,時間就越長
    Execute:消耗在排列每個發(fā)送過來的幀的順序的時間.或者說是CPU告訴GPU渲染一幀的時間,這是一個阻塞調用,因為CPU會一直等待GPU發(fā)出接到命令的回復。所以這個時間,一般都很短。
    Draw + Prepare+Process + Execute = 完整顯示一幀 ,這個時間要小于16ms才能保存每秒60幀。

  2. 計算總數據的行數 frame_count = row_num, 計算每行渲染時間render_time = Draw + Prepare+Process + Execute, 當渲染時間>16.67ms(1000/60),按照垂直同步機制,該幀已經渲染超時

  3. 一旦render_time>16.67 算一次jank(丟幀),一旦jank,需要用掉額外的vsync
    vsync_overtime = 向上取整(render_time/16.67) - 1
    比如:render_time = 66.68 vsync_overtime = 3
    render_time = 67 vsync_overtime = 4
    一次命令執(zhí)行獲得的fps = int( frame_count * 60 / (frame_count + vsync_overtime_sum))

還有一個命令是: adb shell dumpsys SurfaceFlinger --latency LayerName

這個命令能獲取游戲/視頻應用的fps數據

其中LayerName在各個不同系統(tǒng)中獲取的命令是不一樣的
在Android 6系統(tǒng)直接就是SurfaceView
在Android 7系統(tǒng)中可以通過 dumpsys window windows | grep mSurface | grep SurfaceView 然后通過數據截取到
在Android 8系統(tǒng)中可以通過 dumpsys SurfaceFlinger | grep android包名獲取到

執(zhí)行命令結果如下:


計算方法比較簡單,一般打印出來的數據是129行(部分機型打印兩次257行,但是第一部分是無效數據,取后半部分),取len-2的第一列數據為end_time,取len-128的第一列數據為start_time
fps = 127/((end_time - start_time) / 1000000.0)
至于為啥要取第一列數據,這里不做過多介紹,歡迎參看這兩篇文章
老羅的文章SurfaceView原理
Android性能測試之fps獲取
至于為啥要處于1000000,因為命令打印出來的是納秒單位,要轉為毫秒進行計算,127就是因為命令一次打印出來127幀的數據而已

adb CPU占用率數據采集

有兩種方法可以獲取
1) adb shell "top -n 5 | grep <package | pid>" ,第三列就是實時監(jiān)控的CPU占用率(-n 指定執(zhí)行次數,不需root權限),這邊top命令執(zhí)行需要2到3s左右,一般可以采用busybox 的top命令執(zhí)行,效率會快很多


2) adb shell "dumpsys cpuinfo | grep <package | pid>"
兩種方法直接區(qū)別在于,top是持續(xù)監(jiān)控狀態(tài),而dumpsys cpuinfo獲取的實時CPU占用率數據

adb 耗電量數據采集

adb命令:adb shell "dumpsys batterystats < package | pid>" (Android 5.0后引入)
獲取單個應用的耗電量信息,具體返回結果待研究

adb命令:adb shell "dumpsys battery"
出現信息解讀:
AC powered:false 是否連接AC(電源)充電線
USB powered:true 是否連接USB(PC或筆記本USB插口)充電
Wireless powered:false 是否使用了無線電源
status: 1 電池狀態(tài),2為充電狀態(tài),其他為非充電狀態(tài)
level:58 電量(%)
scale: 100. 電量最大數值
voltage: 3977 當前電壓(mV)
current now: -335232. 當前電流(mA)
temperature:355 電池溫度,單位為0.1攝氏度

technology:Li-poly. 電池種類

adb 采集流量數據

adb 命令:adb shell "dumpsys< package | pid> | grep UID" [通過ps命令,獲取app的UID(安裝后唯一且固定)]
adb shell cat /proc/uid_stat/UID/tcp_rcv [cat為查看命令,讀取tcp_rcv獲取應用接收流量信息(設備重啟后清零)]
adb shell cat /proc/uid_stat/UID/tcp_snd [cat為查看命令,讀取tcp_snd獲取應用發(fā)送流量信息(設備重啟后清零)]
計算流量消耗步驟:

  1. 執(zhí)行一次這兩條命令,獲取到應用的開始接收及發(fā)送的流量
  2. 然后我們再操作應用,執(zhí)行一段時間測試
  3. 再次執(zhí)行上述 2 條命令可以獲取到應用結束時候的接收及發(fā)送的流量,通過相減及得到應用的整體流量消耗

或者還有一種方式獲取應用流量消耗:

  1. 首先獲取應用固定uid
    dumsys package android包名 | grep userId
  2. 執(zhí)行cat /proc/net/xt_qtaguid/stats | grep uid



    其中第6列代表rx_bytes接收的字節(jié)數,第8列為tx_bytes發(fā)送的字節(jié)數
    一個uid可能對應多個進程,把數據累加就行
    兩個時間片中間應用流量的消耗,就計算接收字節(jié)數的差值就行

adb采集CPU溫度

首先判斷類型:
cat /sys/class/thermal/thermal_zone*/type


只有紅框框出來的是有效的
cat /sys/class/thermal/thermal_zone*/temp
獲取CPU溫度


adb采集電池溫度

dumpsys battery | grep temperature 單位0.1攝氏度


adb采集整機CPU使用率和分核CPU使用率

獲取/proc/stat文件內容(無權限限制)


總的cpu時間片是 total = user+nice+system+idle+iowait+irq+softirq
忙碌時間為 notidle = user+nice+system +iowait+irq+softirq
cpu使用率計算方法為,先取開始的total值和忙碌時間notidle,隔一段時間片,再取一次計算total2,notidle2, cpuuse = (notidle2 – notidle) * 100 / (total2 - total)%

PS:由于Android 8權限收緊,在Android 8系統(tǒng)手機內apk內讀取文件內容為空,需要shell權限才可獲取文件內容,下同

adb 采集各核cpu頻率

讀/sys/devices/system/cpu/cpuX/cpufreq/scaling_cur_freq文件的值,X不定,看是幾核手機,scaling_cur_freq是否存在也不一定,需要判斷

至于為啥不取cpuinfo_cur_freq文件的值,原因是android 6,7系統(tǒng)獲取的時候,這個文件shell沒有讀取權限,需要root權限

參考文章:https://blog.csdn.net/long_zhimeng/article/details/45934899

adb獲取當前運行于手機前端的應用的包名

Android 6,7系統(tǒng)可執(zhí)行
dumpsys window windows | grep "mCurrentFocus"

執(zhí)行結果一般為類似:
mCurrentFocus=Window{81caaa5 u0 com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity}
按照一定規(guī)則把com.tencent.mobileqq提取出來即可

adb 采集GPU占用率,目前支持高通GPU芯片(Qualcomm Adreno系列)

直接apk內讀取文件即可,不需要shell權限(支持到Android8)
Gpu使用率獲取:會得到兩個值,(前一個/后一個)*100%=使用率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpubusy

Gpu工作頻率:
adb shell cat /sys/class/kgsl/kgsl-3d0/gpuclk
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/cur_freq

Gpu最大、最小工作頻率:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/max_freq
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/min_freq

Gpu可用頻率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpu_available_frequencies
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_frequencies

Gpu可用工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_governors

Gpu當前工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/governor

注意事項

  1. 所有dumpsys命令獲取性能數據,如果adb shell進入終端執(zhí)行,均要求執(zhí)行有shell權限,如果PC端進入終端執(zhí)行,則無此要求
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容

  • 那些年我們用過的顯示性能指標Android客戶端性能優(yōu)化(魅族資深工程師毫無保留奉獻)這一次,我優(yōu)化了37%的內存...
    Art_Collector閱讀 10,432評論 2 22
  • 深圳市金融社保卡個人辦理指南 申辦流程:參保人帶著以下資料到全市12家合作銀行的任一銀行網點申請辦理金融社保卡。 ...
    xiaoxiatess閱讀 9,570評論 0 1
  • 1.關于斷牙 上小學時,需要早上六點起床,有一次起晚了,所以心里焦急,走的匆忙,經過立交橋下的臺階時,摔掉了半顆下...
    肆意不為閱讀 296評論 0 1