ANR 是什么?怎樣避免和解決 ANR?
ANR:Application Not Responding,即應(yīng)用無響應(yīng)
ANR 一般有三種類型:
1. KeyDispatchTimeout(5 seconds)–主要類型:按鍵或觸摸事件在特定時間內(nèi)無響應(yīng)
2. BroadcastTimeout(10 seconds):BroadcastReceiver 在特定時間內(nèi)無法處理完成
3. ServiceTimeout(20 seconds)–小概率類型:Service 在特定的時間內(nèi)無法處理完成超時的原因一般有兩種:(1)當(dāng)前的事件沒有機會得到處理(UI 線程正在處理前一個事件沒有及時完成或者 looper 被某種原因阻塞?。?2)當(dāng)前的事件正在處理,但沒有及時完成。UI 線程盡量只做跟 UI 相關(guān)的工作,耗時的工作(數(shù)據(jù)庫操作、I/O、連接網(wǎng)絡(luò)或者其他可能阻礙 UI 線程的操作)放入單獨的線程處理,盡量用 Handler 來處理 UI thread 和 thread 之間的交互。
ANR 的原因
- 耗時的網(wǎng)絡(luò)訪問
- 大量的數(shù)據(jù)讀寫
- 數(shù)據(jù)庫操作
- 硬件操作(比如 Camera)
- 調(diào)用 thread 的 join()方法、sleep()方法、wait()方法或者等待線程鎖的時候
- service binder 的數(shù)量達到上限
- system server 中發(fā)生 WatchDog ANR
- service 忙導(dǎo)致超時無響應(yīng)
- 其他線程持有鎖,導(dǎo)致主線程等待超時
- 其它線程終止或崩潰導(dǎo)致主線程一直等待
什么是Android 內(nèi)存泄露
Android 內(nèi)存泄漏指的是進程中某些對象(垃圾對象)已經(jīng)沒有使用價值了,但是它們卻可以直接或間接地引用到 gc roots 導(dǎo)致無法被 GC 回收。無用的對象占據(jù)著內(nèi)存空間,使得實際可使用內(nèi)存變小,形象地說法就是內(nèi)存泄漏了。
場景
1. 類的靜態(tài)變量持有大數(shù)據(jù)對象:靜態(tài)變量長期維持到大數(shù)據(jù)對象的引用,阻止垃圾回收。
2. 非靜態(tài)內(nèi)部類的靜態(tài)實例:非靜態(tài)內(nèi)部類會維持一個到外部類實例的引用,如果非靜態(tài)內(nèi)部類的實例是靜態(tài)的,就會間接長期維持著外部類的引用,阻止被回收掉。
3. 資源對象未關(guān)閉:資源性對象如 Cursor、File、Socket,應(yīng)該在使用后及時關(guān)閉。未在 finally 中關(guān)閉,會導(dǎo)致異常情況下資源對象未被釋放的隱患。
4. 注冊對象未反注冊:未反注冊會導(dǎo)致觀察者列表里維持著對象的引用,阻止垃圾回收。
5. Handler 臨時性內(nèi)存泄露:Handler 通過發(fā)送 Message 與主線程交互,Message 發(fā)出之后是存儲在 MessageQueue 中的,有些 Message 也不是馬上就被處理的。在 Message 中存在一個 target,是 Handler 的一個引用,如果 Message 在 Queue 中存在的時間越長,就會導(dǎo)致Handler 無法被回收。如果 Handler 是非靜態(tài)的,則會導(dǎo)致 Activity 或者 Service 不會被回收。
6. 由于 AsyncTask 內(nèi)部也是 Handler 機制,同樣存在內(nèi)存泄漏的風(fēng)險。此種內(nèi)存泄露,一般是臨時性的。
7. 多線程相關(guān)的匿名內(nèi)部類和非靜態(tài)內(nèi)部類:匿名內(nèi)部類同樣會持有外部類的引用,如果在線程中執(zhí)行耗時操作就有可能發(fā)生內(nèi)存泄漏,導(dǎo)致外部類無法被回收,直到耗時任務(wù)結(jié)束,解決辦法是在頁面退出時結(jié)束線程中的任務(wù)。
8.Context 導(dǎo)致內(nèi)存泄漏:禁止聲明靜態(tài)Context變量
9.靜態(tài) View 導(dǎo)致內(nèi)存泄漏
10.WebView 導(dǎo)致的內(nèi)存泄漏:WebView 只要使用一次,內(nèi)存就不會被釋放,所以 WebView 都存在內(nèi)存泄漏的問題,通常的解決辦法是為 WebView 單開一個進程,使用 AIDL 進行通信,根據(jù)業(yè)務(wù)需求在合適的時機釋放掉