Android開發(fā)高手課之崩潰優(yōu)化

《Android開發(fā)高手課》是極客時(shí)間上為數(shù)不多的質(zhì)量高的課程,通過(guò)學(xué)習(xí)確實(shí)讓我開拓了眼界,之前對(duì)于Android的優(yōu)化可能僅僅停留在基礎(chǔ)的階段,通過(guò)對(duì)這個(gè)課程的學(xué)習(xí),確實(shí)了解了更多的監(jiān)測(cè)手段以及優(yōu)化手段。

Android兩種崩潰

  1. Java崩潰: 在Java代碼中,出現(xiàn)了未捕獲的異常,導(dǎo)致程序異常退出
  2. Native崩潰: 一般都是因?yàn)樵贜ative代碼中訪問(wèn)非法地址,也可能是地址對(duì)齊出現(xiàn)了問(wèn)題,或者發(fā)生了程序主動(dòng)abort,這些都會(huì)產(chǎn)生相應(yīng)的signal信號(hào),導(dǎo)致程序異常退出。

Native崩潰捕獲

  1. 編譯端. 編譯c/c++代碼時(shí),需要將帶符號(hào)信息的文件保留下來(lái)
  2. 客戶端. 捕獲到崩潰時(shí),將收集到盡可能多的有用信息寫入日志,然后選擇合適的時(shí)機(jī)上傳到服務(wù)器
  3. 服務(wù)端. 讀取客戶端上報(bào)的日志文件,尋找適合的符號(hào)文件,生成可讀的c/c++調(diào)用棧
image.png

BreakPad是目前Native崩潰中最成熟的方案

選擇合適的崩潰服務(wù)

  1. 騰訊Bugly: 除了有crash數(shù)據(jù)還有運(yùn)營(yíng)數(shù)據(jù)
  2. UC 啄木鳥:可以捕獲Java、Native異常,被系統(tǒng)強(qiáng)殺的異常,ANR,Low Memory Killer、killProcess。技術(shù)深度以及捕獲能力強(qiáng)
  3. 網(wǎng)易云捕:繼承便捷,訪問(wèn)快,捕獲以及上報(bào)速度及時(shí),支持實(shí)時(shí)報(bào)警,提供多種報(bào)警選項(xiàng),可以自定義參數(shù)。
  4. Google的Firebase
  5. crashlytics:服務(wù)器在國(guó)外,訪問(wèn)速度慢,會(huì)丟掉數(shù)據(jù)
  6. 友盟:crash之后會(huì)在再次啟動(dòng)的時(shí)候上報(bào)數(shù)據(jù),所以不能立即獲得這部分信息

客觀的衡量崩潰

  1. UV崩潰率:崩潰造成的用戶影響范圍,UV崩潰率 = 發(fā)生崩潰的UV / 登錄UV
  2. 異常率UV異常率 = 發(fā)生異常退出或崩潰的UV / 登錄UV
  3. PV崩潰率
  4. 啟動(dòng)崩潰率
  5. 重復(fù)崩潰率

使用安全模式:天貓App啟動(dòng)保護(hù)實(shí)踐來(lái)解決啟動(dòng)崩潰的問(wèn)題

檢測(cè)應(yīng)用ANR異常的方法

  1. 使用FileObserver監(jiān)聽 /data/anr/trace.txt的變化。很多高版本的系統(tǒng)沒(méi)有這個(gè)權(quán)限
  2. 監(jiān)控消息隊(duì)列的運(yùn)行時(shí)間,無(wú)法準(zhǔn)確判斷是否會(huì)出現(xiàn)ANR,而且也無(wú)法得到完整的ANR日志。

應(yīng)用退出情況總結(jié)

  1. 主動(dòng)自殺 Process.killProcess、exit()等
  2. 崩潰 出現(xiàn)了Java或Native崩潰
  3. 系統(tǒng)重啟
  4. 被系統(tǒng)殺死,被low memory killer或用戶從后臺(tái)任務(wù)中移除
  5. ANR

在應(yīng)用啟動(dòng)的時(shí)候設(shè)定標(biāo)志,在主動(dòng)自殺或崩潰(單獨(dú)統(tǒng)計(jì))后更新日志,下次啟動(dòng)檢查該標(biāo)志就能確認(rèn)運(yùn)行期間是否發(fā)生過(guò)異常退出,通過(guò)這個(gè)檢測(cè),可以反映ANR、low memory killer、系統(tǒng)強(qiáng)殺、死機(jī)、斷電等其他無(wú)法正常捕獲到的異常。

崩潰現(xiàn)場(chǎng)的信息采集

崩潰信息

  1. 進(jìn)程名、線程名。崩潰是發(fā)生在前臺(tái)進(jìn)程還是后臺(tái)進(jìn)程,是否發(fā)生在UI線程
  2. 崩潰堆棧和類型

系統(tǒng)信息

  1. Logcat:系統(tǒng)的event logcat會(huì)記錄App運(yùn)行的一些基本情況,在文件 /system/etc/event-log-tags中
  2. 機(jī)型,系統(tǒng),廠商,CPU,ABI,Linux版本等
  3. 設(shè)備狀態(tài),是否root,是否是模擬器等

內(nèi)存信息

  1. 系統(tǒng)剩余內(nèi)存:對(duì)于系統(tǒng)內(nèi)存狀態(tài),可以讀取/proc/meminfo
  2. 應(yīng)用使用內(nèi)存:包括java內(nèi)存,RSS,PSS
  3. 虛擬內(nèi)存:可以通過(guò)/proc/self/status得到,通過(guò)/proc/self/maps文件可以得到具體的分布情況

資源信息

  1. 文件句柄fd:文件句柄限制通過(guò)/proc/self/limits獲得,一般單個(gè)進(jìn)程允許打開的最大文件句柄個(gè)數(shù)是1024,超過(guò)800個(gè)比較危險(xiǎn)
  2. 線程數(shù),超過(guò)400個(gè)比較危險(xiǎn)
  3. JNI

應(yīng)用信息

  1. 崩潰場(chǎng)景,發(fā)生的Activity或Fragment
  2. 關(guān)鍵操作路徑
  3. 其他自定義信息

獲取Logcat方法

  1. 通過(guò)logcat命令獲取
    優(yōu)點(diǎn):非常簡(jiǎn)單,兼容性好。
    缺點(diǎn):整個(gè)鏈路比較長(zhǎng),可控性差,失敗率高,特別是堆破壞或者堆內(nèi)存不足時(shí),基本會(huì)失敗。
  2. hook liblog.so實(shí)現(xiàn)。通過(guò)hook liblog.so 中__android_log_buf_write 方法,將內(nèi)容重定向到自己的buffer中。
    優(yōu)點(diǎn):簡(jiǎn)單,兼容性相對(duì)還好。
    缺點(diǎn):要一直打開。
  3. 自定義獲取代碼。通過(guò)移植底層獲取logcat的實(shí)現(xiàn),通過(guò)socket直接跟logd交互。
    優(yōu)點(diǎn):比較靈活,預(yù)先分配好資源,成功率也比較高。
    缺點(diǎn):實(shí)現(xiàn)非常復(fù)雜

獲取Java 堆棧

native崩潰時(shí),通過(guò)unwind只能拿到Native堆棧。我們希望可以拿到當(dāng)時(shí)各個(gè)線程的Java堆棧

  1. Thread.getAllStackTraces()
    優(yōu)點(diǎn):簡(jiǎn)單,兼容性好。
    缺點(diǎn):
    a. 成功率不高,依靠系統(tǒng)接口在極端情況也會(huì)失敗。
    b. 7.0之后這個(gè)接口是沒(méi)有主線程堆棧。
    c. 使用Java層的接口需要暫停線程
  2. hook libart.so。
    通過(guò)hook ThreadList和Thread的函數(shù),獲得跟ANR一樣的堆棧。為了穩(wěn)定性,我們會(huì)在fork子進(jìn)程執(zhí)行。
    優(yōu)點(diǎn):信息很全,基本跟ANR的日志一樣,有native線程狀態(tài),鎖信息等等。
    缺點(diǎn):黑科技的兼容性問(wèn)題,失敗時(shí)可以用Thread.getAllStackTraces()兜底

擴(kuò)展閱讀

  1. Android 平臺(tái) Native 代碼的崩潰捕獲機(jī)制及實(shí)現(xiàn)
  2. master - breakpad/breakpad - Git at Google
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 所有知識(shí)點(diǎn)已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)? 在 Jav...
    侯蛋蛋_閱讀 2,713評(píng)論 1 4
  • ==================================================== 一:什么...
    愛情小傻蛋閱讀 10,107評(píng)論 3 31
  • 這里強(qiáng)烈建議把前面兩篇文章看一遍,因?yàn)榍懊鎯善恼聦?duì)后面大家對(duì)android的IPC的理解幫助很大,本片文章主要內(nèi)...
    Sophia_dd35閱讀 984評(píng)論 0 4
  • 今天爸爸會(huì)回江西去給姐姐慶祝姐姐考上大學(xué)了,明天一天都會(huì)是姐姐的酒席,過(guò)完明天爸爸就會(huì)回來(lái)的。 ...
    米婭MiaChen閱讀 109評(píng)論 0 1
  • 以前小時(shí)候不懂事,姨媽剛來(lái)的時(shí)候沒(méi)啥感覺,家長(zhǎng)讓戒涼戒熱我總是當(dāng)耳旁風(fēng)??偢杏X哪有她們大人說(shuō)的那么夸...
    橙狒狒閱讀 416評(píng)論 0 0

友情鏈接更多精彩內(nèi)容