崩潰優(yōu)化之Java層crash原理分析-創(chuàng)新互聯(lián)

一、造成系統(tǒng)崩潰(crash)的原因是什么? 未捕獲的異常

有Java層面,和Native層面。

成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括循化網(wǎng)站建設(shè)、循化網(wǎng)站制作、循化網(wǎng)頁(yè)制作以及循化網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,循化網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到循化省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

在我們平常操作中,如果有未捕獲的異常,會(huì)導(dǎo)致系統(tǒng)崩潰,這個(gè)崩潰本質(zhì)上是人為操作的,人為去操作系統(tǒng)主動(dòng)退出(后面講源碼的地方可以看到)。

ANR

系統(tǒng)因?yàn)榫€程阻塞問(wèn)題,導(dǎo)致的無(wú)響應(yīng)。

WTF(What a Terrible Failure)

一般指,系統(tǒng)中自己編碼沒(méi)有按照android要求進(jìn)行,例如發(fā)送未受保護(hù)的廣播、啟動(dòng)的Activity未在注冊(cè)文件里注冊(cè)等等;

這個(gè)一般不用太關(guān)注,主要寫(xiě)代碼按標(biāo)準(zhǔn)來(lái)就行。


二、java層未捕獲的異常是如何導(dǎo)致崩潰的 源碼分析步驟1

首先我們先明確一個(gè)目的,我們的main函數(shù)的啟用本身作為主線程存在,那么在我們想要探索系統(tǒng)到底如何處理異常,需要去關(guān)注到一個(gè)類(lèi)Thread;

在我們的程序代碼中,如果存在一個(gè)異常,任何地方都沒(méi)有去捕獲處理它的話,它就會(huì)一路往上拋,最終來(lái)到main函數(shù),如果main函數(shù)也沒(méi)有處理這個(gè)異常,就會(huì)給到JVM來(lái)處理,JVM會(huì)給到當(dāng)前的線程Thread來(lái)處理。

源碼分析步驟2

在Thread類(lèi)中,看到一段這樣的函數(shù)dispatchUncaughtException();

注釋翻譯為:向處理程序發(fā)送未捕獲的異常。此方法旨在僅由JVM調(diào)用;可以理解為,未處理的異常會(huì)走到這里來(lái):

在上圖我們可以看到官方明確告知,JVM在處理未經(jīng)捕獲的異常時(shí),會(huì)調(diào)用當(dāng)前dispatchUncaughtException函數(shù)進(jìn)行處理,這個(gè)里面我們能看到一個(gè)類(lèi)型為UncaughtExceptionHandler的類(lèi)。

在上圖的邏輯中我們可以看到如果沒(méi)有設(shè)置uncaughtExceptionHandler,將使用線程所在的線程組(ThreadGroup)來(lái)處理這個(gè)未捕獲異常。線程組ThreadGroup實(shí)現(xiàn)了UncaughtExceptionHandler,所以可以用來(lái)處理未捕獲異常。

源碼分析步驟3

所以,我們重點(diǎn)來(lái)看ThreadGroup中,是如何來(lái)處理未捕獲異常的:在Thread類(lèi)的dispatchUncaughtException函數(shù)中,最后調(diào)用了getUncaughtExceptionHandler().uncaughtException(this, e); 我們知道這個(gè)getUncaughtExceptionHandler()返回的是ThreadGroup,所以我們來(lái)看ThreadGroup中的uncaughtException方法:

默認(rèn)情況下,ThreadGroup處理未捕獲異常的邏輯是:

  1. 首先將異常消息通知給父線程組(如果parent不為空的話);

  1. 然后嘗試?yán)靡粋€(gè)默認(rèn)的defaultUncaughtExceptionHandler來(lái)處理異常;

  1. 如果沒(méi)有默認(rèn)的異常處理器則將錯(cuò)誤信息輸出打印到System.err。

這里可以思考下,我們可以自定義一個(gè)異常處理類(lèi),繼承下 Thread.UncaughtExceptionHandler,然后去處理未捕獲的異常。記得需要手動(dòng)去調(diào)用Thread.setUncaughtExceptionPreHandler()方法設(shè)置下,有了這個(gè)自定義異常處理類(lèi),就可以做相應(yīng)的崩潰優(yōu)化。

源碼分析步驟4

回到Thread中,思考下:既然他是通過(guò)getDefaultUncaughtExceptionHandler來(lái)處理,現(xiàn)在我們并沒(méi)有看到有相關(guān)的設(shè)置,但是在Thread中我們看到了他對(duì)外提供了對(duì)應(yīng)的設(shè)置函數(shù):Thread.setUncaughtExceptionPreHandler()。

源碼分析步驟5

思考下:系統(tǒng)是否會(huì)有地方默認(rèn)給我們?cè)O(shè)置了uncaughtExceptionHandler?

因?yàn)閺纳厦娴脑创a看來(lái),我們并沒(méi)有看到有讓系統(tǒng)直接崩潰掉的情況,因?yàn)槟J(rèn)是ThreadGroup去處理,他只不過(guò)是做了一個(gè)日志信息的記錄,不會(huì)有退出的情況,那么肯定是有哪個(gè)地方默認(rèn)設(shè)置了uncaughtExceptionHandler,讓系統(tǒng)退出的。

源碼分析步驟6

來(lái)看下RuntimeInit這個(gè)類(lèi),zygote負(fù)責(zé)啟動(dòng)RuntimeInit進(jìn)程(作用:app運(yùn)行時(shí)環(huán)境初始化,用來(lái)初始化運(yùn)行時(shí)的一系列信息,其中包含異常處理),它里面有個(gè)main方法:

這里設(shè)置了默認(rèn)的異常處理:KillApplicationHandler。

源碼分析步驟7

我們來(lái)看下KillApplicationHandler:

重點(diǎn)來(lái)看 uncaughtException(Thread t, Throwable e)這個(gè)方法:

看到這里就知道了,默認(rèn)的異常處理(殺進(jìn)程)是在RuntimeInit進(jìn)程(作用:app運(yùn)行時(shí)環(huán)境初始化,用來(lái)初始化運(yùn)行時(shí)的一系列信息,其中包含異常處理)的main()方法里設(shè)置的。

小總結(jié)
三、AMS如何承接應(yīng)用的異常信息上報(bào)?

在上面的源碼分析步驟7我們知道了,在KillApplicationHandler的uncaughtException()方法里,最終異常信息有一個(gè)AMS上報(bào)過(guò)程:

來(lái)看下ActivityManagerService.handleApplicationCrash()方法:

從上面可以看出,若傳入app為null時(shí),processName就設(shè)置為system_server,意思是:如果沒(méi)有來(lái)源默認(rèn)判定是系統(tǒng)進(jìn)程自己。接著看handleApplicationCrashInner(String eventType......)方法:

參數(shù)eventType是指事件類(lèi)型,具體如下:

  • Java層未捕捉的異常:crash

  • ANR:anr

  • native層的異常:native_crash

現(xiàn)在我們看的是java的異常,所以這個(gè)類(lèi)型傳的是crash。

接著看handleApplicationCrashInner()函數(shù):

中間的可以先不管他們,這個(gè)可以理解為在進(jìn)行系統(tǒng)日志輸出,具體的處理是在addErrorToDropBox()函數(shù)中。

重點(diǎn)注意:無(wú)論是java crash、native_crash、ANR或是wtf,最終都是來(lái)到這里,交由addErrorToDropBox()函數(shù)去處理。


四、DropBoxManager

addErrorToDropBox()函數(shù)和DropBoxManager有關(guān),Android Dropbox 是 Android 在 Froyo(API level 8) 引入的用來(lái)持續(xù)化存儲(chǔ)系統(tǒng)數(shù)據(jù)的機(jī)制。主要用于記錄 Android 運(yùn)行過(guò)程中, 內(nèi)核, 系統(tǒng)進(jìn)程, 用戶進(jìn)程等出現(xiàn)嚴(yán)重問(wèn)題時(shí)的 log, 可以認(rèn)為這是一個(gè)可持續(xù)存儲(chǔ)的系統(tǒng)級(jí)別的 logcat。

記錄位置:在data/system/dropbox中:

也就是說(shuō),我們想要看系統(tǒng)的崩潰日志,可以在這個(gè)文件路徑下找。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

當(dāng)前題目:崩潰優(yōu)化之Java層crash原理分析-創(chuàng)新互聯(lián)
標(biāo)題URL:http://bm7419.com/article48/cescep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開(kāi)發(fā)、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站制作軟件開(kāi)發(fā)、云服務(wù)器網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)