成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

在線“殺死” App 的卡頓難題!

原創
移動開發 Android 系統運維
本?將為大家分享作者是如何在?個?內降低 50% 的 ANR 線上問題發?率的探索與實踐,希望能對開發者有所幫助或啟發。

ANR(Application Not Response)是安卓開發團隊經常遇到的無響應問題,但卻很難定位和根除。尤其是線上問題,由于難以復現,導致開發者難以有效地快速解決。為此,本?將為大家分享作者是如何在?個?內降低 50% 的 ANR 線上問題發?率的探索與實踐,希望能對開發者有所幫助或啟發。

Google 的一項內部研究表明,過高的崩潰與 ANR 發生率會直接影響應用的評分情況,并且很難在商店中累積起用戶量,嚴重影響應用在商店的排名情況。這一系列的連鎖反應將會給應用帶來很大的損失,且有可能失去在應用商店獲得谷歌推薦的資格。因此,ANR 問題對于?多數安卓團隊來說十分棘手,尤其是線上問題令人頭疼。因為本地問題可以復現,線上 ANR 卻很難。因而探究線上 ANR 問題的治理?案更具意義。

觸因與流程分析

1. 關于 ANR

從用戶側看, ANR 問題是指?戶在使?應?過程中出現了嚴重卡頓或卡死時,系統給出的?響應提示彈窗。而從系統側看,ANR 問題就是 AMS 在執?特定?法時出現的超時錯誤,觸發點有四個:

  • InputDispatching Timeout
  • BroadcastQueue Timeout
  • Service Timeout
  • ContentProvider Timeout

系統的 ANR 觸發流程?致可分為兩個部分:

?戶可以直觀感受到的 ANR 彈窗,這部分由 AMS 處理。

同時 AMS 還會發出?個 SIGQUIT 信號:  SignalCatcher 線程會接收到這個信號,并且處理后續的 dump 邏輯;市?上的 ANR 錯誤收集 SDK?部分都依賴于這個原理。

2. 現狀與挑戰

根據美圖秀秀 Android 端的線上監控數據表現, ANR 問題?乎是崩潰問題的兩倍。在這種情況下,?先要考慮的就是如何將問題數量降低,然后再考慮后續?案。

?對大批問題,?先就是對數據進?分析、歸類和梳理以便找出頭部問題。美圖秀秀的線上頭部問題分布如下:

這些問題經過簡單分析后,得出了如下結論:

nativePollOnce 問題,暫時不能依賴現有的?志信息得出結論。不過其占?較?,要放在?優先級處理。processPendingWork 問題已經有可靠的處理?案。占?不低,應該放在較?的優先級處理。

剩余問題數量相近,所以處理順序并不固定。

分析與實踐

在分析具體問題之前,?先跟?家分享?下筆者在處理問題過程中總結的?些經驗。

我們遇到的絕?部分問題,都可以分為兩類:

有源問題:是指可以直接溯源、定位到的問題;有源問題通常可以直接解決,其處理結果直接影響到線上的某個指標(如:相應問題的發?次數,發?率等等)

?源問題:問題成因不定且沒有確定的線索;?對?源問題更多時候需要“?膽假設,??求證” 。通常?源問題需要更多的現場信息以及側?證據來溯源。成功溯源之后的?源問題可轉換成?個或 多個有源問題。

當?系列問題有了明確的優先級以及分類之后,我們就可以開始分析單體 Case 了。

1. MessageQueue.nativePollOnce 問題

線上上報的堆棧如上圖所示。棘手之處在于:如果只看上報的堆棧和錯誤?志,很難排查出問題的根本原因。上?提到過,處理這類問題要“?膽假設”,其可能的原因有:

  • 主線程狀態異常導致“停頓”
  • 卡頓堆棧漂移
  • 其他未知原因
  • 有了假設之后,就需要“??求證”了:
  • 假設主線程異常,那么因何產??
  • 假設卡頓堆棧漂移,那么真實的卡頓堆棧在哪??

1.1 主線程卡死情況

Android 應?啟動過程中有這樣的?段邏輯:zygote 初始化 →RuntimeInit 初始化。在 RuntimeInit 初始化過程中會注冊?個默認的錯誤處理器來響應異常,如下所示:

默認的異常處理機制會在線程發? Crash 時同步給 ActivityThread、ActivityManagerService 之后再“kill”掉?身。

那么如果當主線程發?異常的情況下,不使?系統的處理鏈路或異常處理過程中耗時過久就會發? ANR。當主線程發?了崩潰后其實已處于終?狀態。此時主線程 Looper 的 MessageQueue 組件?法繼續添加新的消息,? Android 應?的運?恰恰依賴的就是主線程的消息輪詢 -- 線上這個錯誤堆棧也是指向了 MessageQueue 組件在等待新消息的到來。因此,當主線程發?異常并?法及時 kill 掉進程時,系統就  會觸發 ANR 超時機制。按照以上的邏輯推斷,我們通過埋點找出了線上異常處理鏈的各個?法耗時數據:

通過對?各個異常處理?法的耗時可以發現,Firebase 異常分析 SDK 在異常處理鏈路中耗時最?。預計移除此組件可降低該問題的發?數量。

最終在去除 Firebase 異常分析 SDK 的版本上線之后,線上數據顯示整體的 ANR 率都有所下降。

接下來分析另?種情況:

1.2 卡頓堆棧漂移

在這種情況下,錯誤上報中的卡頓堆棧已經失真,?法反映出當時現場的真實的情況。因此,增加線上的慢函數監控可以更準確地分析此問題。

線上慢函數監控的原理:

查看 Looper 的源碼得知:主線程所有執?的任務都在 Looper.loop() ?法中的 msg.target.dispatchMessage 中派發執?。在這?有個 Printer 組件分別在消息的執?前、后會 有?個打印的?法調?。可通過 Looper.setMessageLogging ?法設置?個 Printer ,來監控每   個 Message 的執?時間:

監控邏輯的關鍵代碼:

在后期,我們通過這種?式獲得了以下慢函數數據:

整理后得到的分布數據:

不難得出:

【QueuedWork.processPendingWork】、【??創建】類型的問題占?最?,必須優先處理。下?將詳細分析這兩個問題。

回到上?錯誤處理的思路中:

此問題的處理中,使?了通?的?源問題處理?案。通過   【假設 -> 驗證 -> 上線 ->數據變化 】這?流程,最終減少了此問題的發?或轉換成了有源問題。當然,這個問題的誘因不只以上兩個猜想,還有更多的可能需要進?步探索。

2. QueuedWork.processPendingWork 問題處理

問題調?棧:

對 AndroidFrameWork 源碼接觸較少的同學們,可能并不了解這個類的作?。這時候可以借助 Android 源碼搜索引擎來?看究竟:

通過對源碼的分析,可以得出?個?致流程:

SharedPreferencesImpl.apply() ?法中調?  QueuedWork.add() 將  SharedPreferences  的寫 ?任務添加進  QueuedWork 的任務隊列中,之后 ActivityThread 在?些組件?命周期?法中執?了 QueuedWork.waitToFinish → QueuedWork.processPendingWork 這?流程。這?個?命周期方法有:

  • handleStopService
  • handlePauseActivity
  • handleStopActivity
  • handleSleeping

以上的?命周期?法都會先等待 QueuedWork 中的異步隊列執?完成,再執?后續的流程。

很容易得出這樣的結論:SharedPreferences 的 apply ?法本身設計為異步寫?,?Android 系統為了保證數據有效性會在特定的?命周期?法中等待異步寫?任務的完成。如果這個任務處理耗時過?,就會產? ANR 問題

美圖秀秀內部開發了?款代碼的織??具 MtAjx 。其類似于?家熟知的 AspectJ ,相? AspectJ ?案, 有著更好的兼容性(司內?批項?編譯遇到 AspectJ 的問題)以及更?性化的 API 設計。

在處理這個問題時,我們使?了 MtAjx 來攔截 SharedPreferences 的創建,并返回帶?志輸出功能的 SharedPreferencesWrapper 。

簡化的流程如下:

要完成上?的功能,使? MtAjx 只需要編寫?些簡單的規則即可實現:

接下來可采??動化測試來模擬線上?戶的真實操作,并通過 SharedPreferencesWrapper 的?志對SharedPreferences 寫?頻率進?分析。

最終輸出的數據如下:


?前收集的線索可以推斷出:  GMS 組件的某個操作,?量地調?了 SharedPreferences 的 apply ?法。這個操作可能會使 SharedPreferences 的異步寫?任務創建過多從?導致 ANR。后期處理此問題時,我們對這個組件進?了改造:使? MtAjx 在 GMS 中攔截 SharedPreferences 的創建、獲取操作, 并返回?個安全的 SharedPreferences 實現。?然上線之后,得到的數據跟預估的有些差距:

?身問題減少的?例很?

線上整體 ANR 波動不?

猜測這個問題發?時系統的 IO 負載已?分嚴重,處理部分場景可能收益并不?。于是之后上線了全量的 SharedPreferences 替換來避免此問題發?。

請注意,這?的“全量”并?真正的全量替換,?是排除了?些可能會受到影響的調?。?部分都只涉及 業務,這?不作為核?展開討論;使?“安全的” SharedPreferences 實現只是規避問題,其根本還 是需要降低系統負載。

處理全量 SharedPreferences 替換的處理的?法與?志輸出的流程類似。也采?了 MtAjx ?案來攔 截 SharedPreferences 的創建,并返回?個安全的實現。

此處為了容災,線上做了在線開關作為全量替換的整體控制策略來規避未知?險。

最終,這個策略上線之后,上述問題整體降低了 60%-70%,詳見下圖:

3. 首頁創建問題處理

這個問題是通過前?提到的慢函數數據分析發現的。經過堆棧類聚分析之后,關聯到了線上的兩個指 標:

  • 慢函數——關聯了四個問題。
  • ANR——關聯了 N 個問題,?且問題很分散。

其中,慢函數問題多發?在某些 View 的初始化過程中。下?是?些線上觸發此問題的點:

  • ViewPagerFix.()
  • MainTabItemLayout.()
  • MainActivity.onCreate()
  • HomeTopHeaderLayout.

篩選出上述問題的最終調?棧如下:

所有的卡頓點都落在 Runtime.loadLibrary0() 這個調?上。

線上 ANR 或者慢函數的數據表現也近乎?致:都是?通機型、低端機較多。

經過分析得知,?通機型存在?個 BoostFramework 組件?于加快應?的響應速度:類似的機制 可以在 特定情況下提升調度優先級、CPU 頻率,從?加快應?的響應速度。

但在某些情況下,這種機制會導致應?發?卡頓:BoostFramework 初始化依賴?個 so 的加載。?Runtime.loadlibrary0 是?個 synchronize 修飾的函數,多線程調?必然會存在鎖競爭情況。

美圖秀秀在啟動過程中,存在著?量“異步”加載 so 的操作。如果?線程先于主線程進? Runtime.loadLibrary0 ?法,拿不到鎖的主線程就會等待?線程釋放鎖之后再繼續執?。也就是說,如果某個?線程中存在著耗時較久的 so 加載?為,就會阻塞主線程的 so 加載。

?前 so 的加載時間還是盲區,?法針對性地去處理這個問題。與之前 SharedPreferences 問題處理的思路?樣:使? MtAjx 攔截 System.loadLibrary() ?法并輸出其耗時,最后得到如下數據(部分):

從數據上看,某些 so 加載確實消耗了不少時間。要解決此問題,?前初步的?案有:

盡量降低異步 so 加載對主線程 so 加載產?的影響

嘗試 Hack ?通平臺的 BoostFramework,讓其延遲加載或提前加載

列舉出可以執?的?案如下:

最終上線的?案:

  • 延遲執?異步任務中的 so 加載
  • ?通平臺的 BoostFramewok 加速在合理的時間啟動

對這種系統 Hack,必要的容災還是要做。這?與之前的?案?樣,通過在線開關去決定 BoostFramework 加載時機。

采?最終?案上線之后,得出了?些線上的數據:

  • 關聯 ANR 問題發?數降低 50%
  • 低端機啟動速度提升 13%
  • 低端機 ANR 率降低,最?幅度在 50%

復盤 2、3 兩個問題,都經歷了類似的處理過程:

  • 分析:這?包括對問題的根本原因、原理、發?場景全鏈路進?完整分析
  • 建模:指將問題直觀地“數據化”。如SharedPreferences 的讀寫頻次分析、 so 加載中的加載時常數據分析、以及線上的慢函數、ANR 數據變化。
  • 預估:列舉現有?案的優劣對?,以及可能產?的影響,容災措施等
  • 驗證:最終結果和預估時的進?對?,是否影響到線上關聯問題的核?指標。

4. BinderProxy 問題處理

線上 Binder 問題的堆棧表現多種多樣,不過其最終調?點都是android.os.BinderProxy.transactNative() 方法。

經過分析、查閱資料后,初步得出結論。當出現此類問題時,系統或應?基本都處于以下這些狀態:

  • Binder 本地資源耗盡
  • 遠程服務被頻繁調?,致使遠程服務負載過?
  • 其他資源耗盡情況

這個問題的處理思路跟前?的?較類似:?先是收集不同場景下的 Binder 調?數據,然后針對數據進 ?分析、評估是否存在不合理場景。

不同于之前的例?:Binder 問題最終完全發?在系統層,?法通過 MtAjx 進?攔截。因此,換?種? 式:通過 NativeHook 可以攔截所有的 Binder 調?,從?獲取到 Binder 調?運?期的數據。此處選 擇了 BinderProxy.transact() 作為攔截點:

仍然采??動化測試來模擬線上?戶的使?情況并輸出?份?志,分析后得到如下數據(部分):

數據反映出了?系列問題:

  • 頻繁獲取本身 package 信息:如 versionName,versionCode
  • 頻繁獲取設備信息:如 IMEI,IMSI,?卡地址
  • 頻繁?絡類型檢測,?絡狀態檢測
  • 頻繁訪問本地?錄
  • 頻繁權限檢測

這些?法的調?頻率都出現了異常(有些甚?超過了 View 繪制)。通過匯總整理,輸出?份最終修改結論和建議,供內部或者第三?去修改問題:

以上這些問題經過處理,整體 ANR 問題的發?都有?定程度地降低。所以,?部分 ANR 問題并?單體問題,通常降低整個應?的負載亦可降低整體 ANR 問題的發?率。

復盤思考

經過?整?的問題處理之后,通過復盤得出以下?系列思考。

1. 風險控制

在?險存在的時候,通常有以下?種做法:

本地容災策略

異常發?的時候,?適應去熔斷某些功能并上報。這個途徑?論從效率還是從?戶體驗上來講,都是最 好的。不過本地化意味著通常需要各種規則,各種條件去約束。所以?部分情況下這并不是最好的選擇。

在線開關控制

在觀測到異常數量上升(?為、報警)之后,通過在線開關關閉相應的功能。?前最常?的?法,在? 部分場景下都能適?。

熱修復補丁

在觀測到線上異常之后,通過下發熱修復補丁來避免問題的擴?。不過部分設備、渠道可能會失效。

發布緊急版本

迫不得已情況下使?的下策:緊急版本?論從修復效率還是從?戶體驗來講,都是?較糟糕的選擇。

2. 保持數據的準確 & 完整

完善的基礎數據建設更有助于發現問題

筆者之前接?公司另?個業務的性能優化需求時,發現該業務線的應?并沒有采集線上 ANR 指標,這部分在當時來看完全屬于盲區,并且根本?法評估有多少?戶流失與此關聯。

單?維度的數據,只能反映部分事實,能互相佐證的多維度的數據才更可信

?如性能問題中:ANR 數據、慢函數數據、甚?于啟動時?都能相互印證。

3. 別忽視了“蟻穴”

小問題積累到爆發再填坑,往往會耗費更多的精?。

之前公司內部的 AOP 處理?直使? AspectJ ,前期遇到的問題始終在通過加各種規則去規避。在后期問題爆發的時刻,?開發?套 AOP ?案耗費的??會更多。

沒有外?約束下,?個穩定的系統會逐漸地熵增,從?陷?混亂狀態,代碼也是?樣。

質量差的代碼不僅會拖慢研發效率,?且會增加各種各樣的穩定性隱患。平時不注意的細節會在上百萬、上千萬的?戶?前成倍放?。?如主線程的?次 IO 操作:很多?都覺得“? Kb 的數據?已,沒什么?不了的”,可事實真的是這樣嗎?

未來探索

?論過去、現在還是未來, ANR 問題的處理始終是?項具有挑戰的任務。依靠過去的經驗可以避免?些常見的問題,但是面向未來,還需要探索更多的?式去定位和解決問題。

1. 自研性能監控平臺

發現、預警,到 Bug 跟進,可以將整個開發和交付流程串聯起來。這將是未來性能優化?作的??利器。

2. 抽樣上報的詳細 ANR?志

通過對? Bugly 和 XCrash 上報的 ANR ?志,可以看出 XCrash 上報的信息更適合開發同學進?問題定位。在后期,我們將 XCrash 接?作為?個抽樣的上報?案以補充 ANR 數據,為定位問題提供更有價值的信息。

3. 業務異常關聯數據分析

通過對核?業務的操作路徑和線上的異常數據關聯,可以發現?些平時容易被忽略的問題定位?法。我們關聯了圖?處理的業務與 ANR 或 Crash 的發?時間節點,來定位 ANR 或 Crash 是否與某個業務組件相關聯。

結語

ANR 問題并?單體問題。?部分 ANR 問題只是結果,其中的誘因千奇百怪,?中所述僅只是冰???。后續團隊還需要不斷地去解決新的問題,并持續地將已處理問題歸納、總結、規范,進而才能推?使?,更好地治理 ANR 問題。

注:

?中描述的 MtAjx 暫未公開,如有需要可使? AspectJ 代替

?中?量的經驗來源于前?貢獻;?平有限難免存在紕漏 -- 如有問題歡迎隨時與我交流:i@zhan gyanwei.com

專家介紹

作者張彥偉,美圖秀秀 Android 專家。2019 年加入美圖,現負責美圖秀秀 Android 端優化工作。美圖秀秀是 2008 年 10 月 8 日由廈門美圖科技有限公司研發、推出的一款免費影像處理軟件,全球累計超 10 億用戶,在影像類應用排行上長期保持領先優勢。

責任編輯:薛彥澤 來源: 51CTO
相關推薦

2022-05-02 08:30:46

網絡Wi-Fi

2014-08-27 10:24:16

APP

2013-04-19 10:17:57

波士頓馬拉松爆炸的大數據大數據全球技術峰會

2011-11-21 09:26:32

2017-01-12 15:06:30

AndroidAppActivityMan

2013-03-07 11:33:46

App移動應用盈利

2011-05-30 14:36:06

Android 在線開發 App Invent

2018-11-03 16:29:48

Red HatKDE桌面環境

2019-12-27 14:00:43

傳統IT商業模式

2014-12-15 16:27:54

App推廣

2013-08-13 17:33:17

阿里巴巴BAT

2012-12-25 11:54:44

App Store兒童保護隱私

2021-05-29 10:32:15

XDRSIEM安全

2024-02-26 00:00:00

RAGGeminiLLM

2022-12-26 09:00:07

2020-04-03 21:47:58

網絡安全 數據物聯網

2018-02-25 12:14:20

MITAI技術卡頓

2017-01-12 14:21:25

AndroidFragmentActFragment

2015-01-13 11:17:17

2020-03-27 08:17:01

運維DBA服務器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人综合在线 | 久久久久久亚洲精品 | 亚洲电影专区 | 国产精品18久久久久久久 | 自拍视频精品 | 二区久久| 久久丁香 | 性国产丰满麻豆videosex | 亚洲欧美日韩精品久久亚洲区 | 精品一区av| 亚洲网在线 | 久久久久久影院 | 国产精品美女久久久久aⅴ国产馆 | 久久午夜视频 | 国产精品1区| 国产免费观看一级国产 | 最新伦理片 | 在线观看黄色电影 | 日韩欧美国产精品一区二区三区 | 国产精品久久久久久久毛片 | 精品一二三区在线观看 | 欧美久久一级特黄毛片 | 日韩精品极品视频在线观看免费 | 涩涩鲁亚洲精品一区二区 | 久久毛片 | 亚洲天堂av网 | 2018国产精品 | 国产又色又爽又黄又免费 | 国产精品视频一二三区 | 成人深夜福利 | 久国久产久精永久网页 | 国产精品久久 | 碰碰视频 | 日本a视频| 午夜在线免费观看视频 | 国产视频福利在线观看 | 伊人网综合在线 | 日韩免费在线视频 | 九色国产| 久久久久久国产精品 | 国产日韩一区二区 |