Anr发生时的log分析

(1)Anr类型

     ANR一般有三种类型:

  1. KeyDispatchTimeout(5 seconds) –主要类型按键或触摸事件在特定时间内无响应 (No response to an input event (such as key press or screen touch events) within 5 seconds.)

  2. BroadcastTimeout(10 seconds) –BroadcastReceiver在特定时间内无法处理完成 (A BroadcastReceiver hasn’t finished executing within 10 seconds.)

  3. ServiceTimeout(20 seconds) –小概率类型 Service在特定的时间内无法处理完成  (Service timeout 20s)

 

(2)ANR产生的原因

    一、超时的原因一般有两种(超时计时时间点:超时时间计时,一般是从按键分发给app开始):

          1.当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)

          2.当前的事件正在处理,但没有及时完成

 

   二、需要满足的条件:

        1.主线程:只有应用的主线程响应超时才会导致ANR

        2.超时时间(Timeout):导致ANR的原因不同,系统限定的时间也不同,但只要超过时间上限,系统就会发出Signal 3,产生ANR

        3.输入操作/特定操作:输入操作指按键、触屏等操作,特定操作指广播、服务中执行耗时方法等。

 

    三、引起ANR的根本原因总的来说如下三点:

       1.应用程序自身引起的

            例如,主线程阻塞(block)、挂起、死锁、死循环、执行耗时操作等

       2.其他应用进程引起的

           例如,其他进程的CPU占用率过高、某一时刻系统CPU负载过高等,都会导致当前进程无法抢到CPU时间片。

       3.IO wait

           例如,文件读写耗时较久,占用CPU时间片较长,导致ANR

 

(3)如分析发生Anr时的log

   一、Anr发生的流程

      无论是四大组件或者进程等只要发生ANR,最终都会调用AMS.appNotResponding()方法,下面从这个方法说起。

      http://gityuan.com/2016/12/02/app-not-response/   该博客分析发生流程分析的特别透彻,请仔细看看。

 

  二、分析Anr

      分支Anr问题,只能从两方面下手,logcat日志和 /data/anr/trace.txt文件。

       1.logcat日志

        先获取logcat的log,用"ActivityManager"和Process作为关键字, 可以得到下面的信息。可以得到ANR发生在哪个进程, reason, 在ANR发生前一段时间和发生后的一段时间, CPU占用率的统计信息.

例子:

13:12:14.123 I/Process(  220): Sending signal. PID: 21404 SIG: 3---发生ANR的时间和生成trace.txt的时间,注意SIG:3

ANR in com.jingdong.app.mall  
PID: 32125  
Reason: Broadcast of Intent { act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) }  
Load: 46.56 / 39.05 / 35.55  
CPU usage from 3511ms to -9295ms ago:        ----CPU 在ANR 发生前的使用情况
  34% 3656/com.UCMobile:ppappstore: 31% user + 2.9% kernel / faults: 7553 minor 12 major  
  20% 949/system_server: 14% user + 5.7% kernel / faults: 2595 minor 37 major  
  19% 250/installd: 0.5% user + 18% kernel / faults: 4 minor  
  15% 192/mmcqd/0: 0% user + 15% kernel  
  6.6% 105/kswapd0: 0% user + 6.6% kernel  
  5.2% 4648/com.cleanmaster.mguard_cn:service: 3.8% user + 1.4% kernel / faults: 8806 minor 107 major  
  3.9% 23691/com.tencent.mobileqq: 2.2% user + 1.6% kernel / faults: 249 minor 1 major  
  3.7% 32125/com.jingdong.app.mall: 3.2% user + 0.5% kernel / faults: 1528 minor 45 major  
  2.8% 1254/com.android.systemui: 2.2% user + 0.5% kernel / faults: 1057 minor 2 major  
  2.7% 4736/com.android.defcontainer: 0.2% user + 2.5% kernel / faults: 624 minor 1 major  
  1.6% 631/sensors.qcom: 0.3% user + 1.2% kernel / faults: 24 minor  
  1.6% 4825/com.cleanmaster.mguard_cn:worker: 1.3% user + 0.3% kernel / faults: 3783 minor 42 major  
  0.5% 244/debuggerd: 0.2% user + 0.3% kernel / faults: 3331 minor 135 major  
  1.3% 1403/com.android.phone: 1% user + 0.2% kernel / faults: 682 minor 20 major  
  1.1% 363/sdcard: 0% user + 1% kernel / faults: 2 minor  
  0.5% 3/ksoftirqd/0: 0% user + 0.5% kernel  
  0.5% 246/surfaceflinger: 0% user + 0.5% kernel / faults: 126 minor 7 major  
  0.3% 3858/ com.jm.android.jumei: 0.1% user + 0.2% kernel / faults: 515 minor 1 major  
  0.3% 5908/kworker/u:3: 0% user + 0.3% kernel  
  0.3% 7383/kworker/u:7: 0% user + 0.3% kernel  
  0.3% 34/kworker/u:1H: 0% user + 0.3% kernel  
  0.1% 1456/com.oppo.oppogestureservice: 0.1% user + 0% kernel / faults: 305 minor  
  0.3% 2039/mpdecision: 0% user + 0.3% kernel / faults: 2 minor  
  0.3% 2657/kworker/u:5: 0% user + 0.3% kernel  
  0.3% 25301/ksoftirqd/3: 0% user + 0.3% kernel  
  0.2% 7/kworker/u:0H: 0% user + 0.2% kernel  
  0.2% 1994/irq/33-cpubw_hw: 0% user + 0.2% kernel  
  0% 27040/com.baidu.map.location: 0% user + 0% kernel / faults: 659 minor 2 major  
  0% 28522/com.android.keyguard: 0% user + 0% kernel / faults: 465 minor 1 major  
  0.1% 212/flush-179:0: 0% user + 0.1% kernel  
  0.1% 234/servicemanager: 0% user + 0.1% kernel / faults: 7 minor  
95% TOTAL: 25% user + 21% kernel + 41% iowait + 7.7% softirq  
CPU usage from 8382ms to 8907ms later with 99% awake:    ----CPU在ANR发生后的使用情况
  23% 250/installd: 0% user + 23% kernel / faults: 4 minor  
  13% 192/mmcqd/0: 0% user + 13% kernel  
  5.7% 949/system_server: 1.9% user + 3.8% kernel / faults: 18 minor  
    3.8% 1007/ActivityManager: 0% user + 3.8% kernel  
    1.9% 1229/system_server: 1.9% user + 0% kernel  
    1.9% 1507/Binder_E: 1.9% user + 0% kernel  
  3.8% 4736/com.android.defcontainer: 0% user + 3.8% kernel / faults: 8 minor  
    3.8% 4748/Binder_2: 0% user + 3.8% kernel  
  1.9% 105/kswapd0: 0% user + 1.9% kernel  
  0.9% 214/jbd2/mmcblk0p28: 0% user + 0.9% kernel  
  0.9% 246/surfaceflinger: 0% user + 0.9% kernel  
    0.9% 246/surfaceflinger: 0% user + 0.9% kernel  
    0.9% 385/DispSync: 0% user + 0.9% kernel  
  1% 754/mdss_fb0: 0% user + 1% kernel  
  1% 1254/com.android.systemui: 1% user + 0% kernel / faults: 65 minor 1 major  
    1% 1254/ndroid.systemui: 1% user + 0% kernel  
  1.3% 27040/com.baidu.map.location: 0% user + 1.3% kernel / faults: 1 minor  
100% TOTAL: 4.6% user + 25% kernel + 66% iowait + 3.7% softirq

 

注意:

CPU usage from 3511ms to -9295ms ago:

CPU usage from 8382ms to 8907ms later with 99% awake:

这ago和later分别代表anr发生前和发生后。framework层 com.android.internal.os包下,ProcessCpuTracker类用来获取相对时间间隔内的cpu使用情况,会维护两个时间点,mLastSampleTime和mCurrentSampleTime两个采样时间戳,

当发生Anr后会调用

final public String printCurrentState(long now)  传入发生Anr的时间戳,从而获得ANR发生前和发生的cpu使用情况。

AMS中,final void appNotResponding()发生Anr后,会调用该函数,其中又这样一段代码,调用上述的printCurrentState两次,从而在logcat中打印出了ago和later的日志。

代码如下,


  2./data/anr/traces.txt

      trace就不过多介绍,说一下容易忽略点,就是主线程后面跟的那个线程状态, "main" prio=5 tid=1NATIVE  ,这个native代表当前主线程的状态,这个是Thread.cpp中定义线程的状态,有时候直接看这个状态,就能猜出Anr的原因。

     Linux线程和java线程状态对照表:



总结:

  google官网对ANR介绍较少,我只找到了一篇文章 https://developer.android.com/training/articles/perf-anr.html?hl=zh-cn#Avoiding

猜你喜欢

转载自blog.csdn.net/dl6655/article/details/79321581