ANR 是什么邓夕?怎樣避免和解決 ANR刘莹?
ANR:Application Not Responding,即應(yīng)用無響應(yīng)
ANR 一般有三種類型:
1. KeyDispatchTimeout(5 seconds)–主要類型:按鍵或觸摸事件在特定時(shí)間內(nèi)無響應(yīng)
2. BroadcastTimeout(10 seconds):BroadcastReceiver 在特定時(shí)間內(nèi)無法處理完成
3. ServiceTimeout(20 seconds)–小概率類型:Service 在特定的時(shí)間內(nèi)無法處理完成超時(shí)的原因一般有兩種:(1)當(dāng)前的事件沒有機(jī)會(huì)得到處理(UI 線程正在處理前一個(gè)事件沒有及時(shí)完成或者 looper 被某種原因阻塞追俑铡)(2)當(dāng)前的事件正在處理点弯,但沒有及時(shí)完成。UI 線程盡量只做跟 UI 相關(guān)的工作矿咕,耗時(shí)的工作(數(shù)據(jù)庫操作抢肛、I/O、連接網(wǎng)絡(luò)或者其他可能阻礙 UI 線程的操作)放入單獨(dú)的線程處理碳柱,盡量用 Handler 來處理 UI thread 和 thread 之間的交互捡絮。
ANR 的原因
- 耗時(shí)的網(wǎng)絡(luò)訪問
- 大量的數(shù)據(jù)讀寫
- 數(shù)據(jù)庫操作
- 硬件操作(比如 Camera)
- 調(diào)用 thread 的 join()方法、sleep()方法士聪、wait()方法或者等待線程鎖的時(shí)候
- service binder 的數(shù)量達(dá)到上限
- system server 中發(fā)生 WatchDog ANR
- service 忙導(dǎo)致超時(shí)無響應(yīng)
- 其他線程持有鎖锦援,導(dǎo)致主線程等待超時(shí)
- 其它線程終止或崩潰導(dǎo)致主線程一直等待
什么是Android 內(nèi)存泄露
Android 內(nèi)存泄漏指的是進(jìn)程中某些對(duì)象(垃圾對(duì)象)已經(jīng)沒有使用價(jià)值了,但是它們卻可以直接或間接地引用到 gc roots 導(dǎo)致無法被 GC 回收剥悟。無用的對(duì)象占據(jù)著內(nèi)存空間灵寺,使得實(shí)際可使用內(nèi)存變小,形象地說法就是內(nèi)存泄漏了区岗。
場(chǎng)景
1. 類的靜態(tài)變量持有大數(shù)據(jù)對(duì)象:靜態(tài)變量長(zhǎng)期維持到大數(shù)據(jù)對(duì)象的引用略板,阻止垃圾回收。
2. 非靜態(tài)內(nèi)部類的靜態(tài)實(shí)例:非靜態(tài)內(nèi)部類會(huì)維持一個(gè)到外部類實(shí)例的引用慈缔,如果非靜態(tài)內(nèi)部類的實(shí)例是靜態(tài)的叮称,就會(huì)間接長(zhǎng)期維持著外部類的引用,阻止被回收掉藐鹤。
3. 資源對(duì)象未關(guān)閉:資源性對(duì)象如 Cursor瓤檐、File、Socket娱节,應(yīng)該在使用后及時(shí)關(guān)閉挠蛉。未在 finally 中關(guān)閉,會(huì)導(dǎo)致異常情況下資源對(duì)象未被釋放的隱患肄满。
4. 注冊(cè)對(duì)象未反注冊(cè):未反注冊(cè)會(huì)導(dǎo)致觀察者列表里維持著對(duì)象的引用谴古,阻止垃圾回收。
5. Handler 臨時(shí)性內(nèi)存泄露:Handler 通過發(fā)送 Message 與主線程交互稠歉,Message 發(fā)出之后是存儲(chǔ)在 MessageQueue 中的掰担,有些 Message 也不是馬上就被處理的。在 Message 中存在一個(gè) target怒炸,是 Handler 的一個(gè)引用带饱,如果 Message 在 Queue 中存在的時(shí)間越長(zhǎng),就會(huì)導(dǎo)致Handler 無法被回收横媚。如果 Handler 是非靜態(tài)的纠炮,則會(huì)導(dǎo)致 Activity 或者 Service 不會(huì)被回收月趟。
6. 由于 AsyncTask 內(nèi)部也是 Handler 機(jī)制灯蝴,同樣存在內(nèi)存泄漏的風(fēng)險(xiǎn)恢口。此種內(nèi)存泄露,一般是臨時(shí)性的穷躁。
7. 多線程相關(guān)的匿名內(nèi)部類和非靜態(tài)內(nèi)部類:匿名內(nèi)部類同樣會(huì)持有外部類的引用耕肩,如果在線程中執(zhí)行耗時(shí)操作就有可能發(fā)生內(nèi)存泄漏,導(dǎo)致外部類無法被回收问潭,直到耗時(shí)任務(wù)結(jié)束猿诸,解決辦法是在頁面退出時(shí)結(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)存就不會(huì)被釋放梳虽,所以 WebView 都存在內(nèi)存泄漏的問題,通常的解決辦法是為 WebView 單開一個(gè)進(jìn)程灾茁,使用 AIDL 進(jìn)行通信窜觉,根據(jù)業(yè)務(wù)需求在合適的時(shí)機(jī)釋放掉