那些年我們用過的顯示性能指標
Android客戶端性能優(yōu)化(魅族資深工程師毫無保留奉獻)
這一次碱妆,我優(yōu)化了37%的內存
Android性能測試之fps獲取
Android應用性能測試之CPU和內存占用
android如何查看cpu的占用率和內存泄漏
如何解決CPU使用率過高問題
ADB Shell Commands
Android應用性能測試
強烈推薦轉載-Android 性能測試(抱歉,沒找到原文)
Android 性能測試實踐(四) 流量
測試維度
- CPU占用率
- 內存使用
- 響應時間/加載速度
- 顯示性能(FPS)
- 電量、流量
- Crash
- ANR
命令介紹
本文涉及到的命令主要有:
-
>
表示輸出內容寫入到文件 eg.echo 121212 > 12.txt
-
>>
表示輸出內容追加到文件 eg.echo 343434 >> 12.txt
-
Ctrl + c
快捷鍵:終止命令 adb shell
-
ps
查看進程的腻脏,查看某一進程adb shell ps <packageName>
而非adb shell ps | grep <packageName>
-
top
查看占用率top -d 1 | grep com.baidu.BaiduMap
(以百度地圖為例推穷,每一秒打印一次資源利用情況) -
adb shell dumpsys <service name>
打印當前系統(tǒng)信息勘伺。 -
adb shell dumpsys
輸出信息的開始部分就是所有運行的service怠褐; -
adb shell service list
同樣查看所以運行的service
查詢到運行的system service后屋群,就可以在dumpsys后面加上service的名字闸婴,查看指定的service信息。
adb shell dumpsys activity
adb shell dumpsys cpuinfo
adb shell dumpsys battery
adb shell dumpsys window(最后部分可以看到分辨率的信息)
有些service能夠接收額外的參數芍躏,我們可以使用-h查看幫助信息邪乍。
adb shell dumpsys package -h
adb shell dumpsys activity -h
-
adb shell cat /proc/cpuinfo
查看CPU信息 -
adb shell cat /proc/stat
查看CPU使用率 -
adb shell dumpsys gfxinfo <packageName>
查看幀率FPS -
adb shell pm list package
列出所有的包名 -
adb shell dumpsys package
:列出所有的安裝應用的信息 -
adb shell dumpsys package <packageName>
:查看某個包的具體信息
更多內容請參考:ADB Shell Commands
維度分析
CPU占用率
-
CPU使用背景知識
在開發(fā)過程中,我們會遇到手機的CPU使用率過高而引發(fā)的問題纸肉,那接下來溺欧,我對這方面知識做些整理及歸納:
CPU利用率是指:CPU執(zhí)行非系統(tǒng)空閑進程的時間 / CPU總的執(zhí)行時間。
而Android關于進程使用率的限制:
前臺進程不超過95%,后臺進程5%, 但是在系統(tǒng)沒有前臺進程時柏肪,后臺進程可以超過5%
(關于什么是前/后臺進程姐刁,我就不啰嗦了)
-
可能引發(fā)的問題
整體性能降低
界面卡頓
響應慢,容易引起ANR
-
數據獲取
-
通過ADT中的DDMS來查看
adb shell $ dumpsys cpuinfo|grep <package>
-
擴展閱讀
top命令如下
130|shell@hnSCL-Q:/ $ 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.// 顯示幫助文檔
- 查看前5個進程CPU情況
shell@hnSCL-Q:/ $ top -m 5 -s cpu
User 1%, System 2%, IOW 0%, IRQ 0%
User 9 + Nice 1 + Sys 18 + Idle 595 + IOW 0 + IRQ 0 + SIRQ 0 = 623
PID PR CPU% S #THR VSS RSS PCY UID Name
11003 0 2% R 1 2788K 1228K unk shell top
409 0 0% S 8 9864K 1376K fg root /system/bin/jankservice
872 0 0% S 172 1885420K 199516K unk system system_server
207 2 0% S 1 0K 0K fg root ksoftirqd/2
2904 0 0% S 6 5708K 276K unk shell /sbin/adbd
注:PCY顯示是前臺進程(fg)還是后臺進程(bg)的
日志說明(來自:Android應用性能測試)
User 35%, System 13%, IOW 0%, IRQ 0% // CPU占用率
User 109 + Nice 0 + Sys 40 + Idle 156 + IOW 0 + IRQ 0 + SIRQ 1 = 306 // CPU使用情況
PID CPU% S #THR VSS RSS PCY UID Name // 進程屬性
xx xx% x xx xx xx xx xx xx
CPU占用率:
User 用戶進程
System 系統(tǒng)進程
IOW IO等待時間
IRQ 硬中斷時間
CPU使用情況(指一個最小時間片內所占時間烦味,單位jiffies聂使”诶或者指所占進程數):
User 處于用戶態(tài)的運行時間,不包含優(yōu)先值為負進程
Nice 優(yōu)先值為負的進程所占用的CPU時間
Sys 處于核心態(tài)的運行時間
Idle 除IO等待時間以外的其它等待時間
IOW IO等待時間
IRQ 硬中斷時間
SIRQ 軟中斷時間
進程屬性:
PID 進程在系統(tǒng)中的ID
CPU% 當前瞬時所以使用CPU占用率
S 進程的狀態(tài)柏靶,其中S表示休眠弃理,R表示正在運行,Z表示僵死狀態(tài)屎蜓,N表示該進程優(yōu)先值是負數痘昌。
#THR 程序當前所用的線程數
VSS Virtual Set Size 虛擬耗用內存(包含共享庫占用的內存)
RSS Resident Set Size 實際使用物理內存(包含共享庫占用的內存)
PCY OOXX,不知道什么東東
UID 運行當前進程的用戶id
Name 程序名稱android.process.media
// ps:內存占用大小有如下規(guī)律:VSS >= RSS >= PSS >= USS
// PSS Proportional Set Size 實際使用的物理內存(比例分配共享庫占用的內存)
// USS Unique Set Size 進程獨自占用的物理內存(不包含共享庫占用的內存)
- 查看CPU信息
adb shell cat /proc/cpuinfo
- 查看CPU總使用率 :在/proc/stat 下有詳細的CPU使用情況炬转,可以使用命令
adb shell cat /proc/stat
shell@hnSCL-Q:/ $ cat proc/stat
cpu 17082742 1298092 14400241 128401698 1072426 4115 524675 0 0 0
CPU后面的幾位數字分別是
user 從系統(tǒng)啟動開始累計到當前時刻辆苔,處于用戶態(tài)的運行時間,不包含 nice值為負進程扼劈。
nice 從系統(tǒng)啟動開始累計到當前時刻驻啤,nice值為負的進程所占用的CPU時間
system 從系統(tǒng)啟動開始累計到當前時刻,處于核心態(tài)的運行時間
idle 從系統(tǒng)啟動開始累計到當前時刻荐吵,除IO等待時間以外的其它等待時間
iowait 從系統(tǒng)啟動開始累計到當前時刻骑冗,IO等待時間
irq 從系統(tǒng)啟動開始累計到當前時刻,硬中斷時間
softirq 從系統(tǒng)啟動開始累計到當前時刻先煎,軟中斷時間
所以totalCpuTime這個7個屬性的和.
CPU總數用率的算法是:100*((totalCpuTimeS-totalCpuTimeF) -(idelS-idelF))/ (totalCpuTimeS-totalCpuTimeF)
詳細內容參考:Android獲取cpu使用率,剩余內存和硬盤容量
- 查看當前進程的CPU使用率:/proc/pid/stat下則是該pid的CPU使用情況贼涩。先找到自己的進程pid,然后再查看(例如查看com.le.bbs)
shell@hnSCL-Q:/ $ ps com.le.bbs
USER PID PPID VSIZE RSS WCHAN PC NAME
u0_a170 961 374 1603376 96532 ffffffff 00000000 S com.le.bbs
shell@hnSCL-Q:/ $ cat /proc/961/stat
961 (com.le.bbs) S 374 374 0 0 -1 4194624 83875 0 1 0 2785 532 0 0 20 0 28 0 698
196143 1641857024 24133 4294967295 1 1 0 0 0 0 4612 0 38136 4294967295 0 0 17 1
0 0 0 0 0 0 0 0 0 0 0 0 0
shell@hnSCL-Q:/ $
其中2785 532 0 0
四個數字分別是
utime 該任務在用戶運行狀態(tài)的時間
stime 該任務在核心運行的時間
cutime 所有已死線程在用戶狀態(tài)運行狀態(tài)的時間
cstime 所有已死線程在核心的運行時間
所以processCpuTime為這個四個屬性的和榨婆。當前進行所占CPU的算法是:100*(processCpuTimeS-processCpuTimeF)/(totalCpuTimeS-totalCpuTimeF)
詳細內容參考:Android獲取cpu使用率,剩余內存和硬盤容量
內存使用
-
內存限制
adb shell進入手機磁携,這此參數被紀錄在/system/build.prop中,如果想直接查看可以使用adb shell getprop
dalvik.vm.heapgrowthlimit
單個應用程序最大內存限制,超過這個值會產生OOM
dalvik.vm.heapstartsize
應用啟動后分配的初始內存
dalvik.vm.heapsize
單個java虛擬機最大的內存限制,超過這個值會產生OOM
以下是在dos中,在linux中可以直接adb shell getprop|grep
C:\Users\bugeikan :-)>adb shell
shell@hnSCL-Q:/ $ cat /system/build.prop|grep heapgrowthlimit
dalvik.vm.heapgrowthlimit=192m
shell@hnSCL-Q:/ $ cat /system/build.prop|grep heapstartsize
dalvik.vm.heapstartsize=14m
shell@hnSCL-Q:/ $ cat /system/build.prop|grep heapsize
dalvik.vm.heapsize=512m
shell@hnSCL-Q:/ $
-
數據獲取
- 查看內存使用情況
shell@hnSCL-Q:/ $ dumpsys meminfo com.le.bbs
Applications Memory Usage (kB):
Uptime: 1135059305 Realtime: 7004018879
** MEMINFO in pid 3336 [com.le.bbs] **
Pss Private Private Swapped Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 4169 4136 0 0 5748 5427 320
Dalvik Heap 23306 23028 0 0 34152 29625 4527
Dalvik Other 578 576 0 0
Stack 220 220 0 0
Gfx dev 9600 9600 0 0
Other dev 5 0 4 0
.so mmap 728 188 144 0
.apk mmap 260 0 44 0
.ttf mmap 252 0 128 0
.dex mmap 6444 0 6320 0
.oat mmap 1459 0 368 0
.art mmap 1210 948 0 0
Other mmap 24 4 8 0
Unknown 129 128 0 0
TOTAL 48384 38828 7016 0 39900 35052 4847
Objects
Views: 133 ViewRootImpl: 1
AppContexts: 3 Activities: 1
Assets: 3 AssetManagers: 3
Local Binders: 7 Proxy Binders: 12
Parcel memory: 3 Parcel count: 12
Death Recipients: 0 OpenSSL Sockets: 0
SQL
MEMORY_USED: 0
PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0
shell@hnSCL-Q:/ $
- 查看內存使用率狀況
adb shell top
User 1%, System 3%, IOW 0%, IRQ 0%
User 8 + Nice 0 + Sys 21 + Idle 599 + IOW 0 + IRQ 0 + SIRQ 0 = 628
PID PR CPU% S #THR VSS RSS PCY UID Name
27047 0 2% R 1 2800K 1240K unk shell top
409 0 0% S 8 9864K 1376K fg root /system/bin/jankservice
9883 2 0% S 6 5812K 424K unk shell /sbin/adbd
13754 3 0% S 39 1659460K 59560K bg u0_a68 com.tencent.mobileqq:MSF
注:PCY顯示是前臺進程(fg)還是后臺進程(bg)的
-
內存耗用:VSS/RSS/PSS/USS 的介紹
VSS - Virtual Set Size 虛擬耗用內存(包含共享庫占用的內存)
RSS - Resident Set Size 實際使用物理內存(包含共享庫占用的內存)
PSS - Proportional Set Size 實際使用的物理內存(比例分配共享庫占用的內存)
USS - Unique Set Size 進程獨自占用的物理內存(不包含共享庫占用的內存)
一般來說內存占用大小有如下規(guī)律:VSS >= RSS >= PSS >= USS
響應時間/加載速度
響應時間主要分為3類
- 首次啟動 --應用首次啟動所花費的時間
- 非首次啟動 --應用非首次啟動所花費的時間
- 應用界面切換
-
數據來源
-
adb shell am start -W <pkg/activity>
可參考Android_adb shell am/pm使用
通過使用android提供的DisplayManager來獲取所有Activity的啟動時間良风。
C:\Users\yuhushuan>adb logcat > d:\test\logcat.log
^C
C:\Users\yuhushuan>d:
D:\>cd test
D:\test>find "Displayed" logcat.log > all.log //通過“Displayed”過濾
顯示性能
-
性能指標
指標名稱 | 指標意義 | 基礎數據來源 | 采集方式 | 用途 |
---|---|---|---|---|
FPS | 系統(tǒng)合成幀率 | SurfaceFlinger | adb shell | 監(jiān)控 |
Aggregate frame stats | 應用跳幀次數谊迄、幅度 | FrameInfo | adb shell | 監(jiān)控/上報 |
Jankiness count | (估算)應用跳幀次數 | FrameInfo(128幀) | adb shell | 定位 |
Max accumulated frames | (估算)應用跳幀幅度 | FrameInfo(128幀) | adb shell | 定位 |
SM | 應用繪制輪詢頻率 | Choreographer | 多種方式 | 監(jiān)控 |
Skipped frames | 應用跳幀次數、幅度 | Choreographer | 多種 | 監(jiān)控/定位/上報 |
-
數據來源
命令行獲取
adb shell dumpsys gfxinfo <PackageName>
主要數據來源:gfxinfo(Profile data in ms)
adb shell dumpsys SurfaceFlinger --latency <pkg/activity>
Android性能測試之fps獲取-
數據參考
- FrameInfo 相關指標無法直接進行缺陷定位烟央,但 FrameInfo 當中包含了大量詳盡的繪制基礎數據统诺,對于缺陷定位也有較大幫助;
- 關于缺陷定位過程中連續(xù)掉幀閾值的選取疑俭,可參考維基百科中提到幾個重要的幀率數值:
- 12 fps:由于人類眼睛的特殊生理結構粮呢,如果所看畫面之幀率高于每秒約10-12幀的時候,就會認為是連貫的
- 24 fps:有聲電影的拍攝及播放幀率均為每秒24幀钞艇,對一般人而言已算可接受
- 30 fps:早期的高動態(tài)電子游戲啄寡,幀率少于每秒30幀的話就會顯得不連貫,這是因為沒有動態(tài)模糊使流暢度降低
- 60 fps:在實際體驗中哩照,60幀相對于30幀有著更好的體驗
以上各數據分別對應: 0 幀挺物、1幀、2.5幀飘弧、5~6幀识藤。(這就是為啥選擇3/6的原因)
-
相關閱讀
Fps Versus Frame Time
量化和優(yōu)化用戶與 Android 設備之間的交互
測試顯示性能-基于Android M 開發(fā)者預覽版
電量砚著、流量
-
流量測試,同樣需要引入幾個名詞
中等負荷:應用正常操作
高負荷:應用極限操作流量測試包括以下測試項:
a痴昧、應用首次啟動流量提示
b稽穆、應用后臺連續(xù)運行2小時的流量值
c、應用高負荷運行的流量峰值
d赶撰、應用中等負荷運行時的流量均值 -
數據來源
通過PID
D:\test>adb shell ps com.le.bbs
USER PID PPID VSIZE RSS WCHAN PC NAME
u0_a170 29273 374 1679132 173580 ffffffff 00000000 S com.le.bbs
D:\test>adb shell cat /proc/29273/net/dev > net.txt
D:\test>
以下為net.txt內容:
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
r_rmnet_data7: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
r_rmnet_data4: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
wlan0: 36971167 30768 0 5 0 0 0 0 1731561 20200 0 0 0 0 0 0
r_rmnet_data1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
p2p0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
dummy0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet0: 157348588 265691 0 0 0 0 0 0 41547752 311861 0 0 0 0 0 0
r_rmnet_data6: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
r_rmnet_data3: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
lo: 279636994 548567 0 0 0 0 0 0 279636994 548567 0 0 0 0 0 0
rmnet_data7: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet_data6: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet_data5: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet_data4: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet_data3: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet_data2: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet_data1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rmnet_data0: 152976131 263638 0 0 0 0 0 0 41547752 311861 0 0 0 0 0 0
r_rmnet_data8: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
r_rmnet_data0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
r_rmnet_data5: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
r_rmnet_data2: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
這邊的wlan0代表wifi 上傳下載量標識! 上傳下載量單位是字節(jié)可以/1024換算成KB
這里可以看到下載的字節(jié)數 舌镶、數據包 和 發(fā)送的字節(jié)數 、數據包
小技巧:wlan0這些值如何初始化0 很簡單 你打開手機飛行模式再關掉就清0了
- 通過UID
adb shell cat /proc/<pid>/status
測試pid=29273扣囊,查看結果uid=10170
adb shell cat /proc/net/xt_qtaguid/stats > allnet.txt
find "10170" allnet.txt
D:\test>adb shell cat /proc/net/xt_qtaguid/stats > allnet.txt
D:\test>find "10170" allnet.txt
---------- ALLNET.TXT
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
56 wlan0 0x0 10170 0 10729 55 6033 100 10729 55 0 0 0 0 6033 100 0 0 0 0
57 wlan0 0x0 10170 1 3245372 3410 254265 3412 3245372 3410 0 0 0 0 254265 3412 0
0 0 0
154 rmnet_data0 0x0 10170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
155 rmnet_data0 0x0 10170 1 2261 4 482 5 2261 4 0 0 0 0 482 5 0 0 0 0
其中第6和8列為 rx_bytes(接收數據)和tx_bytes(傳輸數據)包含tcp乎折,udp等所有網絡流量傳輸的統(tǒng)計。一個uid可能對應多個 進程侵歇,所以這有兩行流量是累加的就求和就行。
Crash
-
數據獲取
將crash log上報給服務器吓蘑,不再贅述
第三方工具:友盟統(tǒng)計惕虑、百度統(tǒng)計
ANR
第三方測試工具
- GT
- 安測試
- 騰訊APT