其實和app無關的anr問題分析

每個Android程序員都會遇到anr問題,anr問題的根源是代碼處理中超時,例如超時廣播處理超時10s之類的。處理的方法百度google可以見到千篇一律的主線程不要做耗時操作,這個是沒錯,不過依據我個人這幾年的經驗來看,大部分app遇到的anr問題和app自生是沒有任何關係的。看一份日誌:

08-19 12:14:57.269475  1111  1130 E ANRManager: ANR in com.android.incallui, time=104273863
08-19 12:14:57.269475  1111  1130 E ANRManager: Reason: Broadcast of Intent { act=android.intent.action.SCREEN_OFF flg=0x50000010 }
08-19 12:14:57.269475  1111  1130 E ANRManager: Load: 9.35 / 8.88 / 8.57
08-19 12:14:57.269475  1111  1130 E ANRManager: Android time :[2017-08-19 12:14:57.26] [104277.344]
08-19 12:14:57.269475  1111  1130 E ANRManager: CPU usage from 8312ms to 0ms ago:
08-19 12:14:57.269475  1111  1130 E ANRManager:   99% 1013/kworker/5:2: 0% user + 99% kernel
08-19 12:14:57.269475  1111  1130 E ANRManager:   12% 1111/system_server: 8.9% user + 3.3% kernel / faults: 10372 minor 39 major
08-19 12:14:57.269475  1111  1130 E ANRManager:   5% 19573/com.android.systemui: 2.6% user + 2.4% kernel / faults: 1851 minor 19 major
08-19 12:14:57.269475  1111  1130 E ANRManager:   4.9% 334/surfaceflinger: 2.1% user + 2.7% kernel / faults: 309 minor
08-19 12:14:57.269475  1111  1130 E ANRManager:   2.6% 6479/com.netease.mail: 1.9% user + 0.7% kernel / faults: 3681 minor 119 major
08-19 12:14:57.269475  1111  1130 E ANRManager:   2.4% 215/mmcqd/0: 0% user + 2.4% kernel
08-19 12:14:57.269475  1111  1130 E ANRManager:   0.7% 362/fingerprintd: 0% user + 0.7% kernel / faults: 99 minor 1 major
08-19 12:14:57.269475  1111  1130 E ANRManager:   2% 6614/com.netease.mail:pushservice: 1.2% user + 0.8% kernel / faults: 4560 minor 60 major
08-19 12:14:57.269475  1111  1130 E ANRManager:   0% 32044/kworker/8:1: 0% user + 0% kernel
08-19 12:14:57.269475  1111  1130 E ANRManager:   1.2% 7718/cn.kidyn.qdmedical160:pushservice: 0.8% user + 0.3% kernel / faults: 3180 minor 28 major
08-19 12:14:57.269475  1111  1130 E ANRManager:   0.6% 61/dlpt_notify_thr: 0% user + 0.6% kernel
trace如下:

----- pid 2378 at 2017-08-19 12:14:53 -----
Cmd line: com.android.incallui
...

"main" prio=5 tid=1 Native
  | group="main" sCount=1 dsCount=0 obj=0x76af3f88 self=0x7f8703c400
  | sysTid=2378 nice=0 cgrp=default sched=0/0 handle=0x7f8aec02c0
  | state=S schedstat=( 186406401691 149117611257 631811 ) utm=14323 stm=4317 core=7 HZ=100
  | stack=0x7fc2bda000-0x7fc2bdc000 stackSize=8MB
  | held mutexes=
  at android.hardware.SystemSensorManager$BaseEventQueue.nativeDisableSensor(Native method)
  at android.hardware.SystemSensorManager$BaseEventQueue.disableSensor(SystemSensorManager.java:417)
  at android.hardware.SystemSensorManager$BaseEventQueue.removeAllSensors(SystemSensorManager.java:347)
  at android.hardware.SystemSensorManager.unregisterListenerImpl(SystemSensorManager.java:155)
  - locked <0x019000a9> (a java.util.HashMap)
  at android.hardware.SensorManager.unregisterListener(SensorManager.java:625)
  at android.view.OrientationEventListener.disable(OrientationEventListener.java:108)
  at com.android.incallui.InCallActivity.onStop(InCallActivity.java:470)
  at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1289)
  at android.app.Activity.performStop(Activity.java:6413)
  at android.app.ActivityThread.handleSleeping(ActivityThread.java:3845)
  at android.app.ActivityThread.-wrap19(ActivityThread.java:-1)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1672)
  at android.os.Handler.dispatchMessage(Handler.java:111)
  at android.os.Looper.loop(Looper.java:207)
  at android.app.ActivityThread.main(ActivityThread.java:5727)
  at java.lang.reflect.Method.invoke!(Native method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:752)


mainlog中是說處理廣播超時,如果是廣播處理超時那麼trace日誌中主線程堆棧一定是在廣播處理的onReceive中,但是可見trace中的堆棧和anr所報沒有啥關係。

其實在mainlog中已經給出了anr原因的解釋,pid爲1013的進程佔用了99%的cpu,而且全部是在運行kernel層的代碼。

ANRManager處理超時是不會管具體超時原因的,任何超時都會導致正在處理的app進程拋anr出來,但是有可能和app沒有任何關係,anr的出口肯定是app,拋出anr的app只是正好撞在了槍口上。由於這個anr機制的原因,anr問題永遠不會被消滅,無論你的app代碼寫的效率再高再完美。



發佈了101 篇原創文章 · 獲贊 25 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章