有Java層面,和Native層面。
成都創新互聯公司服務項目包括循化網站建設、循化網站制作、循化網頁制作以及循化網絡營銷策劃等。多年來,我們專注于互聯網行業,利用自身積累的技術優勢、行業經驗、深度合作伙伴關系等,向廣大中小型企業、政府機構等提供互聯網行業的解決方案,循化網站推廣取得了明顯的社會效益與經濟效益。目前,我們服務的客戶以成都為中心已經輻射到循化省份的部分城市,未來相信會繼續擴大服務區域并繼續獲得客戶的支持與信任!在我們平常操作中,如果有未捕獲的異常,會導致系統崩潰,這個崩潰本質上是人為操作的,人為去操作系統主動退出(后面講源碼的地方可以看到)。
ANR系統因為線程阻塞問題,導致的無響應。
WTF(What a Terrible Failure)一般指,系統中自己編碼沒有按照android要求進行,例如發送未受保護的廣播、啟動的Activity未在注冊文件里注冊等等;
這個一般不用太關注,主要寫代碼按標準來就行。
首先我們先明確一個目的,我們的main函數的啟用本身作為主線程存在,那么在我們想要探索系統到底如何處理異常,需要去關注到一個類Thread;
在我們的程序代碼中,如果存在一個異常,任何地方都沒有去捕獲處理它的話,它就會一路往上拋,最終來到main函數,如果main函數也沒有處理這個異常,就會給到JVM來處理,JVM會給到當前的線程Thread來處理。
源碼分析步驟2在Thread類中,看到一段這樣的函數dispatchUncaughtException();
注釋翻譯為:向處理程序發送未捕獲的異常。此方法旨在僅由JVM調用;可以理解為,未處理的異常會走到這里來:
在上圖我們可以看到官方明確告知,JVM在處理未經捕獲的異常時,會調用當前dispatchUncaughtException函數進行處理,這個里面我們能看到一個類型為UncaughtExceptionHandler的類。
在上圖的邏輯中我們可以看到如果沒有設置uncaughtExceptionHandler,將使用線程所在的線程組(ThreadGroup)來處理這個未捕獲異常。線程組ThreadGroup實現了UncaughtExceptionHandler,所以可以用來處理未捕獲異常。
源碼分析步驟3所以,我們重點來看ThreadGroup中,是如何來處理未捕獲異常的:在Thread類的dispatchUncaughtException函數中,最后調用了getUncaughtExceptionHandler().uncaughtException(this, e); 我們知道這個getUncaughtExceptionHandler()返回的是ThreadGroup,所以我們來看ThreadGroup中的uncaughtException方法:
默認情況下,ThreadGroup處理未捕獲異常的邏輯是:
首先將異常消息通知給父線程組(如果parent不為空的話);
然后嘗試利用一個默認的defaultUncaughtExceptionHandler來處理異常;
如果沒有默認的異常處理器則將錯誤信息輸出打印到System.err。
這里可以思考下,我們可以自定義一個異常處理類,繼承下 Thread.UncaughtExceptionHandler,然后去處理未捕獲的異常。記得需要手動去調用Thread.setUncaughtExceptionPreHandler()方法設置下,有了這個自定義異常處理類,就可以做相應的崩潰優化。
源碼分析步驟4回到Thread中,思考下:既然他是通過getDefaultUncaughtExceptionHandler來處理,現在我們并沒有看到有相關的設置,但是在Thread中我們看到了他對外提供了對應的設置函數:Thread.setUncaughtExceptionPreHandler()。
源碼分析步驟5思考下:系統是否會有地方默認給我們設置了uncaughtExceptionHandler?
因為從上面的源碼看來,我們并沒有看到有讓系統直接崩潰掉的情況,因為默認是ThreadGroup去處理,他只不過是做了一個日志信息的記錄,不會有退出的情況,那么肯定是有哪個地方默認設置了uncaughtExceptionHandler,讓系統退出的。
源碼分析步驟6來看下RuntimeInit這個類,zygote負責啟動RuntimeInit進程(作用:app運行時環境初始化,用來初始化運行時的一系列信息,其中包含異常處理),它里面有個main方法:
這里設置了默認的異常處理:KillApplicationHandler。
源碼分析步驟7我們來看下KillApplicationHandler:
重點來看 uncaughtException(Thread t, Throwable e)這個方法:
看到這里就知道了,默認的異常處理(殺進程)是在RuntimeInit進程(作用:app運行時環境初始化,用來初始化運行時的一系列信息,其中包含異常處理)的main()方法里設置的。
小總結在上面的源碼分析步驟7我們知道了,在KillApplicationHandler的uncaughtException()方法里,最終異常信息有一個AMS上報過程:
來看下ActivityManagerService.handleApplicationCrash()方法:
從上面可以看出,若傳入app為null時,processName就設置為system_server,意思是:如果沒有來源默認判定是系統進程自己。接著看handleApplicationCrashInner(String eventType......)方法:
參數eventType是指事件類型,具體如下:
Java層未捕捉的異常:crash
ANR:anr
native層的異常:native_crash
現在我們看的是java的異常,所以這個類型傳的是crash。
接著看handleApplicationCrashInner()函數:
中間的可以先不管他們,這個可以理解為在進行系統日志輸出,具體的處理是在addErrorToDropBox()函數中。
重點注意:無論是java crash、native_crash、ANR或是wtf,最終都是來到這里,交由addErrorToDropBox()函數去處理。
addErrorToDropBox()函數和DropBoxManager有關,Android Dropbox 是 Android 在 Froyo(API level 8) 引入的用來持續化存儲系統數據的機制。主要用于記錄 Android 運行過程中, 內核, 系統進程, 用戶進程等出現嚴重問題時的 log, 可以認為這是一個可持續存儲的系統級別的 logcat。
記錄位置:在data/system/dropbox中:
也就是說,我們想要看系統的崩潰日志,可以在這個文件路徑下找。
你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
當前題目:崩潰優化之Java層crash原理分析-創新互聯
標題URL:http://vcdvsql.cn/article48/cescep.html
成都網站建設公司_創新互聯,為您提供定制開發、網頁設計公司、網站制作、軟件開發、云服務器、網站策劃
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯