2021-04-12想讓安卓app不再卡頓?看這篇文章就夠了

[想讓安卓app不再卡頓涯雅?看這篇文章就夠了]

實(shí)現(xiàn)背景

應(yīng)用的使用流暢度,是衡量用戶體驗(yàn)的重要標(biāo)準(zhǔn)之一划乖。Android 由于機(jī)型配置和系統(tǒng)的不同,項(xiàng)目復(fù)雜App場(chǎng)景豐富迷殿,代碼多人參與迭代歷史較久咖杂,代碼可能會(huì)存在很多UI線程耗時(shí)的操作庆寺,實(shí)際測(cè)試時(shí)候也會(huì)偶爾發(fā)現(xiàn)某些業(yè)務(wù)場(chǎng)景發(fā)生卡頓的現(xiàn)象,用戶也經(jīng)常反饋和投訴App使用遇到卡頓诉字。因此懦尝,我們?cè)絹碓疥P(guān)注和提升用戶體驗(yàn)的流暢度問題。

已有方案

在這之前壤圃,我們將反饋的常見卡頓場(chǎng)景陵霉,或測(cè)試過程中常見的測(cè)試場(chǎng)景使用UI自動(dòng)化來重復(fù)操作睹酌,用adb系統(tǒng)工具觀察App的卡頓數(shù)據(jù)情況,試圖重現(xiàn)場(chǎng)景來定位問題洗出。

常用的方式是使用adb SurfaceFlinger服務(wù)和adb gfxinfo功能,在自動(dòng)化操作app的過程中隘梨,使用adb獲取數(shù)據(jù)來監(jiān)控app的流暢情況,發(fā)現(xiàn)出現(xiàn)出現(xiàn)卡頓的時(shí)間段援雇,尋找出現(xiàn)卡頓的場(chǎng)景和操作钻趋。

方式1:adb shell dumpsys SurfaceFlinger

使用‘a(chǎn)db shell dumpsys SurfaceFlinger’命令即可獲取最近127幀的數(shù)據(jù),通過定期執(zhí)行adb命令,獲取幀數(shù)來計(jì)算出幀率FPS冒签。

優(yōu)點(diǎn):命令簡(jiǎn)單辖所,獲取方便,動(dòng)態(tài)頁(yè)面下數(shù)據(jù)直觀顯示頁(yè)面的流暢度在孝;

缺點(diǎn):對(duì)于靜態(tài)頁(yè)面魔招,無法感知它的卡頓情況峦朗。使用FPS在靜態(tài)頁(yè)面情況下,由于獲取數(shù)據(jù)不變,計(jì)算結(jié)果為0,無法有效地衡量靜態(tài)頁(yè)面卡頓程度戈咳;

通過外部adb命令取得的數(shù)據(jù)信息衡量app頁(yè)面卡頓情況的同時(shí),app層面無法在運(yùn)行時(shí)判斷是否卡頓,也就無法記錄下當(dāng)時(shí)運(yùn)行狀態(tài)和現(xiàn)場(chǎng)信息摇肌。

方式2:adb shell dumpsys gfxinfo

使用‘a(chǎn)db shell dumpsys gfxinfo’命令即可獲取最新128幀的繪制信息雨饺,詳細(xì)包括每一幀繪制的Draw,Process惑淳,Execute三個(gè)過程的耗時(shí)额港,如果這三個(gè)時(shí)間總和超過16.6ms即認(rèn)為是發(fā)生了卡頓。

優(yōu)點(diǎn):命令簡(jiǎn)單歧焦,獲取方便移斩,不僅可以計(jì)算幀率肚医,還可以觀察卡頓時(shí)每一幀的瓶頸處于哪個(gè)維度(onDraw,onProcess向瓷,onExecute)扛施;

缺點(diǎn):同方式1擁有一樣的缺點(diǎn)嚼鹉,無法衡量靜態(tài)頁(yè)面下的卡頓程度;app層面依然無法在發(fā)生卡頓時(shí)獲取運(yùn)行狀態(tài)和信息,導(dǎo)致跟進(jìn)和重現(xiàn)困難扭粱。

已有的兩種方案比較適合衡量回歸卡頓問題的修復(fù)效果和判斷某些特定場(chǎng)景下是否有卡頓情況圆到,然而雇锡,這樣的方式有幾個(gè)明顯的不足:

1壳炎、一般很難構(gòu)造實(shí)際用戶卡頓的環(huán)境來重現(xiàn);

2长搀、這種方式操作起來比較麻煩宇弛,需編寫自動(dòng)化用例,無法覆蓋大量的可疑場(chǎng)景源请,測(cè)試重現(xiàn)耗時(shí)耗人力枪芒;

3、無法衡量靜態(tài)頁(yè)面的卡頓情況谁尸;

4舅踪、出現(xiàn)卡頓的時(shí)候app無法及時(shí)獲取運(yùn)行狀態(tài)和信息,開發(fā)定位困難良蛮。

全新方案

基于這樣的痛點(diǎn)抽碌,我們希望能使用一套有效的檢測(cè)機(jī)制,能夠覆蓋各種可能出現(xiàn)的卡頓場(chǎng)景背镇,一旦發(fā)生卡頓咬展,能幫助我們更方便地定位耗時(shí)卡頓發(fā)生的地方泽裳,記錄下具體的信息和堆棧瞒斩,直接從代碼程度給到開發(fā)定位卡頓問題。我們?cè)O(shè)想的Android卡頓監(jiān)控系統(tǒng)需要達(dá)到幾項(xiàng)基本功能:

1涮总、如何有效地監(jiān)控到App發(fā)生卡頓胸囱,同時(shí)在發(fā)生卡頓時(shí)正確記錄app的狀態(tài),如堆棧信息瀑梗,CPU占用烹笔,內(nèi)存占用,IO使用情況等等抛丽;

2谤职、統(tǒng)計(jì)到的卡頓信息上報(bào)到監(jiān)控平臺(tái),需要處理分析分類上報(bào)內(nèi)容亿鲜,并通過平臺(tái)Web直觀簡(jiǎn)便地展示允蜈,供開發(fā)跟進(jìn)處理。

如何從App層面監(jiān)控卡頓?

我們的思路是饶套,一般主線程過多的UI繪制漩蟆、大量的IO操作或是大量的計(jì)算操作占用CPU,導(dǎo)致App界面卡頓妓蛮。只要我們能在發(fā)生卡頓的時(shí)候怠李,捕捉到主線程的堆棧信息和系統(tǒng)的資源使用信息,即可準(zhǔn)確分析卡頓發(fā)生在什么函數(shù)蛤克,資源占用情況如何捺癞。那么問題就是如何有效檢測(cè)Android主線程的卡頓發(fā)生,目前業(yè)界兩種主流有效的app監(jiān)控方式如下咖耘,在《Android卡頓監(jiān)控方式實(shí)現(xiàn)》這篇文章中我將分別詳細(xì)闡述這兩者的特點(diǎn)和實(shí)現(xiàn)翘簇。

1、利用UI線程的Looper打印的日志匹配儿倒;

2版保、使用Choreographer.FrameCallback

方式3: 利用UI線程的Looper打印的日志匹配判斷是否卡頓

Android主線程更新UI。如果界面1秒鐘刷新少于60次夫否,即FPS小于60彻犁,用戶就會(huì)產(chǎn)生卡頓感覺。簡(jiǎn)單來說凰慈,Android使用消息機(jī)制進(jìn)行UI更新汞幢,UI線程有個(gè)Looper,在其loop方法中會(huì)不斷取出message微谓,調(diào)用其綁定的Handler在UI線程執(zhí)行森篷。如果在handler的dispatchMesaage方法里有耗時(shí)操作,就會(huì)發(fā)生卡頓豺型。

image.png

只要檢測(cè)msg.target.dispatchMessage(msg) 的執(zhí)行時(shí)間仲智,就能檢測(cè)到部分UI線程是否有耗時(shí)的操作,從而判斷是否發(fā)生了卡頓姻氨,并打印UI線程的堆棧信息钓辆。

優(yōu)點(diǎn):用戶使用app或者測(cè)試過程中都能從app層面來監(jiān)控卡頓情況,一旦出現(xiàn)卡頓能記錄app狀態(tài)和信息肴焊, 只要dispatchMesaage執(zhí)行耗時(shí)過大都會(huì)記錄下來前联,不再有前面兩種adb方式面臨的問題與不足。

缺點(diǎn):需另開子線程獲取堆棧信息娶眷,會(huì)消耗少量系統(tǒng)資源似嗤。

方式4: 利用Choreographer.FrameCallback監(jiān)控卡頓

我們知道, Android系統(tǒng)每隔16ms發(fā)出VSYNC信號(hào)届宠,來通知界面進(jìn)行重繪烁落、渲染壳咕,每一次同步的周期為16.6ms,代表一幀的刷新頻率顽馋。SDK中包含了一個(gè)相關(guān)類谓厘,以及相關(guān)回調(diào)。理論上來說兩次回調(diào)的時(shí)間周期應(yīng)該在16ms寸谜,如果超過了16ms我們則認(rèn)為發(fā)生了卡頓竟稳,利用兩次回調(diào)間的時(shí)間周期來判斷是否發(fā)生卡頓(這個(gè)方案是Android 4.1 API 16以上才支持)。

這個(gè)方案的原理主要是通過Choreographer類設(shè)置它的FrameCallback函數(shù)熊痴,當(dāng)每一幀被渲染時(shí)會(huì)觸發(fā)回調(diào)FrameCallback他爸, FrameCallback回調(diào)void doFrame (long frameTimeNanos)函數(shù)。一次界面渲染會(huì)回調(diào)doFrame方法果善,如果兩次doFrame之間的間隔大于16.6ms說明發(fā)生了卡頓诊笤。

image.png

優(yōu)點(diǎn):不僅可用來從app層面來監(jiān)控卡頓,同時(shí)可以實(shí)時(shí)計(jì)算幀率和掉幀數(shù)巾陕,實(shí)時(shí)監(jiān)測(cè)App頁(yè)面的幀率數(shù)據(jù)讨跟,一旦發(fā)現(xiàn)幀率過低,可自動(dòng)保存現(xiàn)場(chǎng)堆棧信息鄙煤。

缺點(diǎn):需另開子線程獲取堆棧信息晾匠,會(huì)消耗少量系統(tǒng)資源。

總結(jié)下上述四種方案的對(duì)比情況:

SurfaceFlinger gfxinfo Looper.loop Choreographer.FrameCallback
監(jiān)控是否卡頓
支持靜態(tài)頁(yè)面卡頓檢測(cè) × ×
支持計(jì)算幀率 ×
支持獲取App運(yùn)行信息 × ×

實(shí)際項(xiàng)目使用中梯刚,我們一開始兩種監(jiān)控方式都用上凉馆,上報(bào)的兩種方式收集到的卡頓信息我們分開處理,發(fā)現(xiàn)卡頓的監(jiān)控效果基本相當(dāng)亡资。同一個(gè)卡頓發(fā)生時(shí)澜共,兩種監(jiān)控方式都能記錄下來。 由于Choreographer.FrameCallback的監(jiān)控方式不僅用來監(jiān)控卡頓锥腻,也方便用來計(jì)算實(shí)時(shí)幀率嗦董,因此我們現(xiàn)在只使用Choreographer.FrameCallback來監(jiān)控app卡頓情況。

痛點(diǎn)1:如何保證捕獲卡頓堆棧的準(zhǔn)確性旷太?

細(xì)心的同學(xué)可以發(fā)現(xiàn)展懈,我們通過上述兩種方案(Looper.loop和Choreographer.FrameCallback)可以判斷是當(dāng)前主線程是否發(fā)生了卡頓销睁,進(jìn)而在計(jì)算發(fā)現(xiàn)卡頓后的時(shí)刻dump下了主線程的堆棧信息供璧。實(shí)際上,通過一個(gè)子線程冻记,監(jiān)控主線程的活動(dòng)情況睡毒,計(jì)算發(fā)現(xiàn)超過閾值后dump下主線程的堆棧,那么生成的堆棧文件只是捕捉了一個(gè)時(shí)刻的現(xiàn)場(chǎng)快照冗栗。打個(gè)不太恰當(dāng)?shù)谋确窖莨耍喈?dāng)于閉路電視監(jiān)控只拍下了兇案發(fā)生后的慘狀供搀,而并沒有錄下這個(gè)案件發(fā)生的過程,那么作為警察的你只看到了結(jié)局钠至,依然很難判斷案情和兇手葛虐。在實(shí)際的運(yùn)用中,我們也發(fā)現(xiàn)這種方式下獲取到的堆棧情況棉钧,查看相關(guān)的代碼和函數(shù)屿脐,經(jīng)常已經(jīng)不是發(fā)生卡頓的代碼了。


image.png

如圖所示宪卿,主線程在T1~T2時(shí)間段內(nèi)發(fā)生卡頓的诵,上述方案中獲取卡頓堆棧的時(shí)機(jī)已經(jīng)是T2時(shí)刻。實(shí)際卡頓可能是這段時(shí)間內(nèi)某個(gè)函數(shù)的耗時(shí)過大導(dǎo)致卡頓佑钾,而不一定是T2時(shí)刻的問題西疤,如此捕獲的卡頓信息就無法如實(shí)反應(yīng)卡頓的現(xiàn)場(chǎng)。

我們看看在這之前微信iOS主線程卡頓監(jiān)控系統(tǒng)是如何實(shí)現(xiàn)的捕獲堆棧休溶。微信iOS的方案是起檢測(cè)線程每1秒檢查一次代赁,如果檢測(cè)到主線程卡頓,就將所有線程的函數(shù)調(diào)用堆棧dump到內(nèi)存中兽掰。本質(zhì)上管跺,微信iOS方案的計(jì)時(shí)起點(diǎn)是固定的,檢查次數(shù)也是固定的禾进。如果任務(wù)1執(zhí)行花費(fèi)了較長(zhǎng)的時(shí)間導(dǎo)致卡頓豁跑,但由于監(jiān)控線程是隔1秒掃一次的,可能到了任務(wù)N才發(fā)現(xiàn)并dump下來堆棧泻云,并不能抓到關(guān)鍵任務(wù)1的堆棧艇拍。這樣的情況的確是存在的,只不過現(xiàn)上監(jiān)控量大走人海戰(zhàn)術(shù)宠纯,通過概率分布抓到卡頓點(diǎn)卸夕,但依然不是最佳的捕獲方案。

因此婆瓜,擺在我們面前的是如何更加精準(zhǔn)地獲取卡頓堆棧快集。為了卡頓堆棧的準(zhǔn)確度,我們想要能獲取一段時(shí)間內(nèi)的堆棧廉白,而不是一個(gè)點(diǎn)的堆棧个初,如下圖:

image.png

我們采用高頻采集的方案來獲取一段卡頓時(shí)間內(nèi)的多個(gè)堆棧,而不再是只有一個(gè)點(diǎn)的堆棧猴蹂。這樣的方案的優(yōu)點(diǎn)是保證了監(jiān)控的完備性院溺,整個(gè)卡頓過程的堆棧都得以采樣、收集和落地磅轻。

具體做法是在子線程監(jiān)控的過程中珍逸,每一輪log輸出或是每一幀開始啟動(dòng)monitor時(shí)逐虚,我們便已經(jīng)開啟了高頻采樣收集主線程堆棧的工作了。當(dāng)下一輪log或者下一幀結(jié)束monitor時(shí)谆膳,我們判斷是否發(fā)生卡頓(計(jì)算耗時(shí)是否超過閾值)叭爱,來決定是否將內(nèi)存中的這段堆棧集合落地到文件存儲(chǔ)。也就是說漱病,每一次卡頓的發(fā)生涤伐,我們記錄了整個(gè)卡頓過程的多個(gè)高頻采樣堆棧。由此精確地記錄下整個(gè)兇案發(fā)生的詳細(xì)過程缨称,供上報(bào)后分析處理(后文會(huì)闡述如何從一次卡頓中多個(gè)堆棧信息中提取出關(guān)鍵堆棧)凝果。

采樣頻率與性能消耗

目前我們的策略是判斷一個(gè)卡頓是否發(fā)生的耗時(shí)閾值是80ms(5*16.6ms),當(dāng)一個(gè)卡頓達(dá)80ms的耗時(shí)睦尽,采集1~2個(gè)堆椘骶唬基本可以定位到耗時(shí)的堆棧。因此采樣堆棧的頻率我們?cè)O(shè)為52ms(經(jīng)驗(yàn)值)当凡。

當(dāng)然山害,高頻采集堆棧的方案,必然會(huì)導(dǎo)致app性能上帶來的影響沿量。為此浪慌,為了評(píng)估對(duì)App的性能影響,在上述默認(rèn)設(shè)置的情況下朴则,我們做一個(gè)簡(jiǎn)單的測(cè)試實(shí)驗(yàn)觀察权纤。實(shí)驗(yàn)方法:ViVoX9 上運(yùn)行微信讀書App,使用卡頓監(jiān)控與高頻采樣乌妒,和不使用卡頓監(jiān)控的情況下汹想,保持兩次的操作動(dòng)作相同,分析性能差異撤蚊,數(shù)據(jù)如下:

關(guān)閉監(jiān)控 打開監(jiān)控 對(duì)比情況(上漲)
CPU 1.07% 1.15% 0.08%
Memory Native Heap 38794 38894 100 kB
Dalvik Heap 25889 26984 1095 kB
Dalvik Other 2983 3099 116 kB
.so mmap 38644 38744 100 kB
沒有線程快照 加上線程快照
性能指標(biāo) 2.4.5.368.91225 2.4.8.376.91678 上漲
CPU CPU 63 64 0.97%
流量KB Flow 28624 28516
內(nèi)存KB NativeHeap 59438 60183 1.25%
DalvikHeap 7066 7109 0.61%
DalvikOther 6965 6992 0.40%
Sommap 22206 22164
日志大小KB file size 294893 1561891 430%
壓縮包大小KB zip size 15 46 206%

從實(shí)驗(yàn)結(jié)果可知古掏,高頻采樣對(duì)性能消耗很小,可以不影響用戶體驗(yàn)侦啸。

監(jiān)控使用Choreographer.FrameCallback, 采樣頻率設(shè)52ms)槽唾,最終結(jié)果是性能消耗帶來的影響很小,可忽略:

1)監(jiān)控代碼本身對(duì)主線程有一定的耗時(shí)光涂,但影響很小庞萍,約0.1ms/S;

2)卡頓監(jiān)控開啟后顶捷,增加0.1%的CPU使用挂绰;

3)卡頓監(jiān)控開啟后屎篱,增加Davilk Heap內(nèi)存約1MB服赎;

4)對(duì)于流量葵蒂,文件可按天寫入,壓縮文件最大約100KB重虑,一天上傳一次

痛點(diǎn)2:海量卡頓堆棧后該如何處理践付?

卡頓堆棧上報(bào)到平臺(tái)后,需要對(duì)上報(bào)的文件進(jìn)行分析缺厉,提取和聚類過程永高,最終展示到卡頓平臺(tái)。前面我們提到提针,每一次卡頓發(fā)生時(shí)命爬,會(huì)高頻采樣到多個(gè)堆棧信息描述著這一個(gè)卡頓。做個(gè)最小的估算辐脖,每天上報(bào)收集2000個(gè)用戶卡頓文件饲宛,每個(gè)卡頓文件dump下了用戶遇到的10個(gè)卡頓,每個(gè)卡頓高頻收集到30個(gè)堆棧嗜价,這就已經(jīng)產(chǎn)生20001030=60W個(gè)堆棧艇抠。按照這個(gè)量級(jí)發(fā)展,一個(gè)月可產(chǎn)生上千萬的堆棧信息久锥,每個(gè)堆棧還是幾十行的函數(shù)調(diào)用關(guān)系家淤。這么大量的信息對(duì)存儲(chǔ),分析瑟由,頁(yè)面展示等均帶來相當(dāng)大的壓力絮重。很快就能撐爆存儲(chǔ)層,平臺(tái)無法展示這么大量的數(shù)據(jù)歹苦,開發(fā)更是沒辦法處理這些多的堆棧問題绿鸣。因而,海量卡頓堆棧成為我們另外一個(gè)面對(duì)的難題暂氯。

在一個(gè)卡頓過程中潮模,一般卡頓發(fā)生在某個(gè)函數(shù)的調(diào)用上罢缸,在這多個(gè)堆棧列表中师逸,我們把每個(gè)堆棧都做一次hash處理后進(jìn)行排重分析,有很大的幾率會(huì)是dump到同一個(gè)堆棧hash蔼啦,如下圖:

image.png

我們對(duì)一個(gè)卡頓中多個(gè)堆棧進(jìn)行統(tǒng)計(jì)辣吃,去重后找出最高重復(fù)次數(shù)的堆棧动遭,發(fā)現(xiàn)堆棧C出現(xiàn)了3次,這次卡頓很有可能就是卡在堆棧3反映的函數(shù)調(diào)用上神得。由于采樣頻率不低厘惦,因此出現(xiàn)卡頓后一般都有不少的卡頓,如此可找出重復(fù)次數(shù)最高的堆棧哩簿,作為重點(diǎn)分析卡頓問題宵蕉,從而進(jìn)行修復(fù)酝静。

舉個(gè)實(shí)際上報(bào)數(shù)據(jù)例子,可以由下圖看到羡玛,一個(gè)卡頓如序號(hào)3别智,在T1~T2時(shí)間段共收集到62個(gè)堆棧,我們發(fā)現(xiàn)大部分堆棧都是一樣的稼稿,于是我們把堆棧hash后嘗試去重薄榛,發(fā)現(xiàn)排重后只有2個(gè)堆棧,而其中某個(gè)堆棧重復(fù)了59次让歼,我們可以重點(diǎn)關(guān)注和處理這個(gè)堆棧反映出的卡頓問題敞恋。

image.png

把一個(gè)卡頓抽離成一個(gè)關(guān)鍵的堆棧的思路,可以大大降低了數(shù)據(jù)量谋右, 前面提及60W個(gè)堆棧就可以縮減為2W個(gè)堆棧(2000101=2W)耳舅。

按照這個(gè)方法,處理后的每個(gè)卡頓只剩下一個(gè)堆棧倚评,進(jìn)而每個(gè)卡頓都有唯一的標(biāo)識(shí)(hash)浦徊。到此,我們還可以對(duì)卡頓進(jìn)行聚類操作天梧,進(jìn)一步排重和縮小數(shù)據(jù)量盔性。分類前對(duì)每個(gè)堆棧,根據(jù)業(yè)務(wù)的不同設(shè)置好過濾關(guān)鍵字呢岗,提取出感興趣的代碼行冕香,去除其他冗余的系統(tǒng)函數(shù)后進(jìn)行歸類。目前主要有兩種方式的分類:

1后豫、按堆棧最外層分類悉尾,這種分類方法把同樣入口的函數(shù)導(dǎo)致的卡頓收攏到一起,開發(fā)修復(fù)對(duì)應(yīng)入口的函數(shù)來解決卡頓挫酿,然而這種方式有一定的風(fēng)險(xiǎn)构眯,可能同樣入口但最終調(diào)用不同的函數(shù)導(dǎo)致的卡頓則會(huì)被忽略;

2早龟、按堆棧最內(nèi)層分類惫霸,這種分類方法能收攏同樣根源問題的卡頓,缺點(diǎn)就是可能忽略調(diào)用方可能有多個(gè)業(yè)務(wù)入口葱弟,會(huì)造成fix不全面壹店。

當(dāng)然,這兩種方式的聚類芝加,從一定程度上分類大量的卡頓硅卢,但不太好控制的是,究竟要取堆棧的多少層作為識(shí)別分類。層數(shù)越多将塑,則聚類結(jié)果變多脉顿,分類更細(xì),問題零碎抬旺;層數(shù)越少弊予,則聚類結(jié)果變少祥楣,達(dá)不到分類的效果开财。這是一個(gè)權(quán)衡的過程,實(shí)際則按照一定的嘗試效果后去劃分層數(shù)误褪,如微信iOS卡頓監(jiān)控采用的策略是一級(jí)分類按最內(nèi)層倒數(shù)2層分類责鳍,二級(jí)分類按最內(nèi)層倒數(shù)4層。

image.png

對(duì)于我們產(chǎn)品兽间,目前我們沒有按層數(shù)最內(nèi)或最外來劃分历葛,直接過濾出感興趣的關(guān)鍵字的代碼后直接分類。這樣的分類效果下來數(shù)據(jù)量級(jí)在承受范圍內(nèi)嘀略,如之前的2W堆椥羧埽可聚類剩下大約2000個(gè)(視具體聚類結(jié)果)。同時(shí)帜羊,每天新上報(bào)的堆棧都跟歷史數(shù)據(jù)對(duì)比聚合咒程,只過濾出未重復(fù)的堆棧,更進(jìn)一步地縮減上報(bào)堆棧的真正存儲(chǔ)量讼育。

卡頓監(jiān)控系統(tǒng)的處理流程

image.png

用戶上報(bào)

目前我們的策略是:

1帐姻、通過后臺(tái)配置下發(fā),灰度0.2%的用戶量進(jìn)行卡頓監(jiān)控和上報(bào)奶段;

2饥瓷、如果用戶反饋有卡頓問題,也可實(shí)時(shí)撈取卡頓日志來分析痹籍;

3呢铆、每天灰度的用戶一個(gè)機(jī)器上報(bào)一次,上報(bào)后刪除文件不影響存儲(chǔ)空間蹲缠。

后臺(tái)解析

1刺洒、主要負(fù)責(zé)處理上報(bào)的卡頓文件,過濾吼砂、去重逆航、分類、反解堆棧渔肩、入庫(kù)等流程因俐;

2、自動(dòng)回歸修復(fù)好的卡頓問題,讀取tapd 卡頓bug單的修復(fù)結(jié)果抹剩,更新平臺(tái)展示撑帖,計(jì)算修復(fù)好的卡頓問題,后續(xù)版本是否重新出現(xiàn)(修復(fù)不徹底)

平臺(tái)展示

上報(bào)處理后的卡頓展示平臺(tái)

http://test.itil.rdgz.org/wel...

主要展示卡頓處理后的數(shù)據(jù):

1澳眷、以版本為維度展示卡頓問題列表胡嘿,按照卡頓上報(bào)重復(fù)的次數(shù)降序列出;

2钳踊、歸類后展示每個(gè)卡頓的關(guān)鍵耗時(shí)代碼衷敌,也可查看全部堆棧內(nèi)容;

3拓瞪、支持操作卡頓記錄缴罗,如搜索卡頓,提t(yī)apd單祭埂,標(biāo)注已解決等面氓;

4、展示每個(gè)版本的卡頓問題修復(fù)數(shù)據(jù)情況蛆橡,版本分布舌界,監(jiān)控修復(fù)后是否重現(xiàn)等。

image.png
image.png

自動(dòng)提單

實(shí)際使用中泰演,為了增強(qiáng)跟進(jìn)效果呻拌,我們?cè)O(shè)立一些規(guī)則,比如卡頓重復(fù)上報(bào)超過100次粥血,卡頓耗時(shí)達(dá)到1000ms等柏锄,自動(dòng)提t(yī)apd bug單給開發(fā)處理,系統(tǒng)也會(huì)自動(dòng)更新卡頓問題的修復(fù)情況和數(shù)據(jù)复亏,開發(fā)只需定期review tapd bug單處理修復(fù)卡頓問題即可趾娃,整個(gè)卡頓系統(tǒng)從監(jiān)控,上報(bào)缔御,分析抬闷,聚類,展示耕突,提單到回歸笤成,整個(gè)流程自動(dòng)化實(shí)現(xiàn),不再需要人工介入眷茁。

實(shí)際應(yīng)用效果

1炕泳、接入產(chǎn)品:微信讀書,企業(yè)微信上祈,QQ郵箱

2培遵、應(yīng)用場(chǎng)景:現(xiàn)網(wǎng)用戶的監(jiān)控浙芙,發(fā)布前測(cè)試的監(jiān)控,每天自動(dòng)化運(yùn)行的監(jiān)控

3籽腕、發(fā)現(xiàn)問題:三個(gè)多月時(shí)間嗡呼,歸類后的卡頓過萬,提bug單約500皇耗,開發(fā)已解決超過200個(gè)卡頓問題

卡頓監(jiān)控的組件化

考慮到Android卡頓監(jiān)控的通用性南窗,除了應(yīng)用于Android WeRead中,我們也推廣到廣研的其他產(chǎn)品中郎楼,如企業(yè)微信万伤,QQ郵箱。因此箭启,在開發(fā)GG的努力下壕翩,推出了卡頓監(jiān)控庫(kù)http://git.code.oa.com/moai/m... 蛉迹,其他Android產(chǎn)品可快速接入卡頓監(jiān)控的SDK來監(jiān)控app卡頓情況傅寡。

目前monitor卡頓監(jiān)控庫(kù)主要有監(jiān)控主線程卡頓情況,獲取平均幀率使用情況北救,高頻采樣和獲取卡頓信息等基本功能荐操。這里要注意幾點(diǎn):

1、采樣堆棧信息的頻率和卡頓耗時(shí)的閾值均可在SDK中設(shè)置珍策;

2托启、SDK默認(rèn)判斷一個(gè)卡頓是否發(fā)生的耗時(shí)閾值是80ms(5*16.6ms)

3、采樣堆棧的頻率是52ms(約3幀+攘宙,盡量錯(cuò)開系統(tǒng)幀率的節(jié)奏屯耸,堆棧可盡量落到繪制幀過程中)

4蹭劈、啟動(dòng)監(jiān)控后疗绣,卡頓日志就會(huì)不斷通過內(nèi)部的writer輸出,實(shí)現(xiàn)MonitorLogWriter.setDelegate才能獲取這些日志铺韧,具體的日志落地和上報(bào)策略因?yàn)楦鱾€(gè)App不同所以沒有集成到SDK中

5多矮、monitor start后一直監(jiān)控主線程, 包括切換到后臺(tái)時(shí)也會(huì)哈打,直到主動(dòng)stop或者app被kill塔逃。所以在切后臺(tái)時(shí)要主動(dòng)stop monitor,切前臺(tái)時(shí)要重新start

1.組件引入方式

image.png

2.主線程卡頓監(jiān)控的使用方式

1)啟動(dòng)監(jiān)控

image.png

2)停止監(jiān)控

image.png

3)獲取卡頓信息

image.png

app中加入監(jiān)控卡頓SDK后,會(huì)實(shí)時(shí)輸出卡頓的時(shí)間點(diǎn)和堆棧信息料仗,我們將這些信息寫入日志文件落地湾盗,同時(shí)每天固定場(chǎng)景上報(bào)到服務(wù)器,如每天上報(bào)一次立轧,用戶打開app后進(jìn)行上報(bào)等策略格粪。收集不同用戶不同手機(jī)不同場(chǎng)景下的所有卡頓堆棧信息丙挽,可供分析,定位和優(yōu)化問題匀借。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末颜阐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子吓肋,更是在濱河造成了極大的恐慌凳怨,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件是鬼,死亡現(xiàn)場(chǎng)離奇詭異肤舞,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)均蜜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門李剖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人囤耳,你說我怎么就攤上這事篙顺。” “怎么了充择?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵德玫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我椎麦,道長(zhǎng)宰僧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任观挎,我火速辦了婚禮琴儿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嘁捷。我一直安慰自己造成,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布普气。 她就那樣靜靜地躺著谜疤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪现诀。 梳的紋絲不亂的頭發(fā)上夷磕,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音仔沿,去河邊找鬼坐桩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛封锉,可吹牛的內(nèi)容都是我干的绵跷。 我是一名探鬼主播膘螟,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼碾局!你這毒婦竟也來了荆残?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤净当,失蹤者是張志新(化名)和其女友劉穎内斯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體像啼,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俘闯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了忽冻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片真朗。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖僧诚,靈堂內(nèi)的尸體忽然破棺而出遮婶,到底是詐尸還是另有隱情,我是刑警寧澤振诬,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布蹭睡,位于F島的核電站衍菱,受9級(jí)特大地震影響赶么,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脊串,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一辫呻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琼锋,春花似錦放闺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至谜叹,卻和暖如春匾寝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荷腊。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工艳悔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人女仰。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓猜年,卻偏偏與公主長(zhǎng)得像抡锈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乔外,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345