About ANR and OOM
1. ANR
1.1 什麼是ANR? ANR(Application Not Responding)
在Android上,如果你的應用程式有一段時間響應不夠靈敏,系統會向用戶顯示一個對話方塊,這個對話方塊稱作應用程式無響應(ANR:ApplicationNotResponding)對話方塊。使用者可以選擇“等待”而讓程式繼續執行,也可以選擇“強制關閉”。所以一個流暢的合理的應用程式中不能出現anr,而讓使用者每次都要處理這個對話方塊。
預設情況下,在android中Activity的最長執行時間是5秒,BroadcastReceiver的最長執行時間則是10秒 (廠商可以定製 這個時間)
1.在5秒內沒有響應輸入的事件。
2.BroadcastReceiver在制定時間內完成。
具體點的原因: 1) IO操作耗時 。 2)資料庫操作複雜耗時。 3)主執行緒 非主執行緒 產生死鎖等待。 4)網路載入/圖片操作耗時。 5)硬體操作耗時。
1) service binder 數量達到上限。 2)Service忙導致超時無響應。
1.3 ANR是哪裡報出來的?
ActivityManagerService 管理每個應用程式是否發生了ANR 。按照ANR發生的不同型別,細緻一點的說:
1)KeyDispatchTimeout :每次dispatch 觸控事件的時候都會檢查當前接收事件的app是否 ready 去處理下一個事件,判斷的過程中會檢查是否發生了ANR。檢查的辦法是ActivityManagerService對比上次記錄的該pid的處理時間和當前時間的差值,是否大於系統規定的ANR超時時間。
2)BroadcastTimeout:ActivityManagerService 管理著幾個broadcastQueue,這些broadcastQueue 管理者不同型別的broadcast。每個broadcast傳送給註冊的物件都有一個時間限制,BroadCastQueue會記錄每次傳送的開始時間以及結束時間,如果超過了ANR規定時間就會發生ANR。通過呼叫AMS中的AppNotResponding來彈出系統彈窗。
3)ServiceTimeout:與KeyDispatchTimeout 類似。(沒有具體的看)
1.4 如何盡力避免ANR?
1)執行在主執行緒裡的任何方法都儘可能少做事情。特別是,Activity應該在它的關鍵生命週期方法(如onCreate()和onResume())裡儘可能少的去做建立操作。(可以採用重新開啟子執行緒的方式,然後使用Handler+Message的方式做一些操作,比如更新主執行緒中的ui等)
2)應用程式應該避免在BroadcastReceiver裡做耗時的操作或計算。但不再是在子執行緒裡做這些任務(因為BroadcastReceiver的生命週期短),替代的是,如果響應Intent ,應用程式應該啟動一個Service。
3)避免在IntentReceiver裡啟動一個Activity,因為它會建立一個新的畫面,並從當前使用者正在執行的程式上搶奪焦點。如果你的應用程式在響應Intent廣播時需要向用戶展示什麼,你應該使用Notification Manager來實現。
1.5 出現ANR如何解決。解決ANR 主要通過 報錯log和Trace檔案分析解決。 從產生的原因入手。 具體方法可以參考一下: http://www.cnblogs.com/purediy/p/3225060.html
2. Crash
Crash 包括很多情況,在進行系統debug的時候很容易區分。 例如JAVA層的Fatal 錯誤, 在log中會明確的打印出具體原因, 是陣列越界/未初始化變數/空指標等。又比如C/C++層的錯誤,會打印出相應的資訊,我們可以通過addr2line 來進行debug。 應用層的crash 是我們常說的FC。 system service 的crash 會導致 系統不能啟動/重啟等問題。
http://blog.csdn.net/god2469/article/details/9713395 (常見的SIG錯誤以及含義)
3. OOM
OOM是指Out Of Memory。每個android應用單獨使用一個Dalvik虛擬機器,每個虛擬機器使用的堆記憶體是有限的,超過了限制就會引發oom錯誤。造成OOM幾乎都是自己的程式碼結構導致的不良。常見的原因:
1)不恰當的使用static關鍵字。 儘量不要使用static儲存物件。
2)內部類對Activity的引用。 內部類物件如果引用Activity物件,同時有很長的宣告週期的話會導致 Activity物件釋放不及時。
3)Bitmap使用。 大量的bitmap會導致 程式包和執行時的記憶體消耗變大。
4)遊標cursor的使用。 Cursor 物件用完應該及時關閉
5)其他的內容。 我個人不能列舉所有的情況。其他的是我暫時沒有想到的 歡迎指教
文章中有一些引用的地方。不算原創。