iOS版界面卡頓監(jiān)測方案

實(shí)現(xiàn)思路
在開始之前苛白,我們先思考一下,界面卡頓是由哪些原因?qū)е碌模?/p>

1.死鎖:主線程拿到鎖 A焚虱,需要獲得鎖 B购裙,而同時(shí)某個(gè)子線程拿了鎖 B,需要鎖 A鹃栽,這樣相互等待就死鎖了躏率。
2.搶鎖:主線程需要訪問 DB,而此時(shí)某個(gè)子線程往 DB 插入大量數(shù)據(jù)民鼓。通常搶鎖的體驗(yàn)是偶爾卡一陣子薇芝,過會(huì)就恢復(fù)了。
3.主線程大量 IO:主線程為了方便直接寫入大量數(shù)據(jù)丰嘉,會(huì)導(dǎo)致界面卡頓夯到。
4.主線程大量計(jì)算:算法不合理,導(dǎo)致主線程某個(gè)函數(shù)占用大量 CPU饮亏。
5.大量的 UI 繪制:復(fù)雜的 UI耍贾、圖文混排等,帶來大量的 UI 繪制路幸。

針對(duì)這些原因荐开,我們可以怎么定位問題呢?
1.死鎖一般會(huì)伴隨 crash简肴,可以通過 crash report 來分析誓焦。
2.搶鎖不好辦,將鎖等待時(shí)間打出來用處不大着帽,我們還需要知道是誰占了鎖杂伟。
3.大量 IO 可以在函數(shù)開始結(jié)束打點(diǎn),將占用時(shí)間打到日志中仍翰。
4.大量計(jì)算同理可以將耗時(shí)打到日志中赫粥。
5.大量 UI 繪制一般是必現(xiàn),還好辦予借;如果是偶現(xiàn)的話越平,想加日志點(diǎn)都沒地方,因?yàn)槭锹谙到y(tǒng)函數(shù)里面灵迫。

如果可以將當(dāng)時(shí)的線程堆棧捕捉下來秦叛,那么上述難題都迎刃而解。主線程在什么函數(shù)哪一行卡住瀑粥,在等什么鎖挣跋,而這個(gè)鎖又是被哪個(gè)子線程的哪個(gè)函數(shù)占用,有了堆棧狞换,我們都可以知道避咆。自然也能知道是慢在UI繪制,還是慢在我們的代碼修噪。
所以查库,思路就是起一個(gè)子線程,監(jiān)控主線程的活動(dòng)情況黄琼,如果發(fā)現(xiàn)有卡頓樊销,就將堆棧 dump 下來。

技術(shù)實(shí)現(xiàn)

1需要解決的問題

原理一旦講出來脏款,好像也不復(fù)雜围苫。魔鬼都是隱藏在細(xì)節(jié)中,效果好不好弛矛,完全由實(shí)現(xiàn)細(xì)節(jié)決定够吩。具體到卡頓檢測,有幾個(gè)問題需要仔細(xì)處理:
怎么知道主線程發(fā)生了卡頓丈氓?
子線程以什么樣的策略和頻率來檢測主線程周循?這個(gè)是要發(fā)布到現(xiàn)網(wǎng)的,如果處理不好万俗,帶來明顯的性能損耗(尤其是電量)湾笛,就不能接受了。
堆棧上報(bào)了上來怎么分類闰歪?直接用 crash report 的分類不適合嚎研。
卡頓 dump 下來的堆棧會(huì)有多頻繁?數(shù)據(jù)量會(huì)有多大?
全量上報(bào)還是抽樣上報(bào)临扮?怎么在問題跟進(jìn)與節(jié)省流量直接平衡论矾?

2判斷標(biāo)準(zhǔn)

怎么判斷主線程是不是發(fā)生了卡頓?一般來說杆勇,用戶感受得到的卡頓大概有三個(gè)特征:

FPS 降低
CPU 占用率很高
主線程 Runloop 執(zhí)行了很久

看起來 FPS 能夠兼容后面兩個(gè)特征贪壳,但是在實(shí)際操作過程中發(fā)現(xiàn) FPS 不好衡量,抖動(dòng)比較大蚜退。而對(duì)于搶鎖或大量 IO 的情況闰靴,光有 CPU 是不行的。所以我們實(shí)際上用到的是下面兩個(gè)準(zhǔn)則:

CPU 占用超過了100%
主線程 Runloop 執(zhí)行了超過2秒

3檢測策略

為了降低檢測帶來的性能損耗钻注,我們仔細(xì)設(shè)計(jì)了檢測線程的策略:

內(nèi)存 dump:每1秒檢查一次蚂且,如果檢查到主線程卡頓,就將所有線程的函數(shù)調(diào)用堆棧 dump 到內(nèi)存中幅恋。
文件 dump:如果內(nèi)存 dump 的堆棧跟上次捕捉到的不一樣杏死,則 dump 到文件中;否則按照斐波那契數(shù)列將檢查時(shí)間遞增(1佳遣,1识埋,2,3零渐,5窒舟,8…)直到?jīng)]有遇到卡頓或卡頓堆棧不一樣。這樣能夠避免同一個(gè)卡頓寫入多個(gè)文件的情況诵盼,也能避免檢測線程圍著同一個(gè)卡頓空轉(zhuǎn)的情況惠豺。

4分類方法

直接用 crash report 的分類方法是不行的,這個(gè)很好理解:最終卡在 lock 函數(shù)的卡頓风宁,外面可能是很多不同的業(yè)務(wù)洁墙,例如可能是讀取消息,可能是讀取聯(lián)系人戒财,等等热监。卡頓監(jiān)控需要仔細(xì)定義自己的分類規(guī)則饮寞⌒⒖福可以是從調(diào)用堆棧的最外層開始?xì)w類,或者是取中間一部分歸類幽崩,或者是取最里面一部分歸類苦始。

各有優(yōu)缺點(diǎn):

最外層歸類:能夠?qū)⑼蝗肟诘目D歸類起來。缺點(diǎn)是層數(shù)不好定慌申,可能外面十來層都是系統(tǒng)調(diào)用陌选,也有可能第一層就是微信的函數(shù)了。
中間層歸類:能夠根據(jù)事先劃分好的“特征值”來歸類。缺點(diǎn)是“特征值”不好定咨油,如果要做到自動(dòng)學(xué)習(xí)生成的話您炉,對(duì)后臺(tái)分析系統(tǒng)要求太高了。
最內(nèi)層歸類:能夠?qū)⑼辉虻目D歸類起來臼勉。缺點(diǎn)是同一分類可能包含不同的業(yè)務(wù)邻吭。

綜合考慮并一一嘗試之后,我們采用了最內(nèi)層歸類的優(yōu)化版宴霸,亦即進(jìn)行二級(jí)歸類。第一級(jí)按照最內(nèi)倒數(shù)2層歸類膏蚓,這樣能夠?qū)⑼辉虻目D集中起來瓢谢;第二級(jí)分類是從第一級(jí)點(diǎn)擊進(jìn)來,然后從最內(nèi)層倒數(shù)4層進(jìn)行歸類驮瞧,這樣能夠?qū)⑼辉虻牟煌瑯I(yè)務(wù)分散歸類起來氓扛。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市论笔,隨后出現(xiàn)的幾起案子采郎,更是在濱河造成了極大的恐慌,老刑警劉巖狂魔,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒜埋,死亡現(xiàn)場離奇詭異,居然都是意外死亡最楷,警方通過查閱死者的電腦和手機(jī)整份,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來籽孙,“玉大人烈评,你說我怎么就攤上這事》附ǎ” “怎么了讲冠?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長适瓦。 經(jīng)常有香客問我竿开,道長,這世上最難降的妖魔是什么犹菇? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任德迹,我火速辦了婚禮,結(jié)果婚禮上揭芍,老公的妹妹穿的比我還像新娘胳搞。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布肌毅。 她就那樣靜靜地躺著筷转,像睡著了一般。 火紅的嫁衣襯著肌膚如雪悬而。 梳的紋絲不亂的頭發(fā)上呜舒,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音笨奠,去河邊找鬼袭蝗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛般婆,可吹牛的內(nèi)容都是我干的到腥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼蔚袍,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼乡范!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起啤咽,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤晋辆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后宇整,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓶佳,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年没陡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涩哟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡盼玄,死狀恐怖贴彼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情埃儿,我是刑警寧澤器仗,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站童番,受9級(jí)特大地震影響精钮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜剃斧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一轨香、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧幼东,春花似錦臂容、人聲如沸科雳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糟秘。三九已至,卻和暖如春球散,著一層夾襖步出監(jiān)牢的瞬間尿赚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國打工蕉堰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凌净,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓嘁灯,卻偏偏與公主長得像泻蚊,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丑婿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,528評(píng)論 25 707
  • 界面卡頓是哪些問題導(dǎo)致的? 死鎖:主線程拿到鎖A没卸,需要獲得鎖B羹奉,而同時(shí)某個(gè)子線程拿了鎖B,需要鎖A约计,這樣互相等待就...
    城市之光閱讀 1,197評(píng)論 0 3
  • 這里是屬于世界的另一個(gè)空間位面诀拭,這里就是修靈界。 修靈界里人人修煉的物質(zhì)能量稱為“靈氣”煤蚌。 修靈界的修士境界分為以...
    易可風(fēng)閱讀 475評(píng)論 2 3
  • 紅塵暢笑風(fēng)月耕挨, 芳華夢(mèng)依長安。 渭溪涼月如眉尉桩, 是非難解虛影筒占。 皓腕拂卷輕紗, 慵看鏡中山色蜘犁。 2015....
    cheri安朵兒閱讀 245評(píng)論 0 4