ANR总结

2019-03-17  本文已影响0人  小的橘子

ANR介绍

ANR全名Application Not Responding, 也就是"应用无响应".

ANR产生原因

只有当应用程序的UI线程响应超时才会引起ANR,超时产生一般有两种

  1. 当前的事件没有机会得到处理,例如UI线程正在响应另外一个事件,当前事件由于某种原因被阻塞
  2. 当前事件正在处理,但由于耗时太长没能及时完成

ANR分类

从发生的场景分类:

  1. Input事件超过5s没有被处理完
  2. Service处理超时,前台20s,后台200s
  3. BroadcastReceiver处理超时,前台10S,后台60s
  4. ContentProvider执行超时,比较少见
    每部分具体时间定义位置如下
    ActivityManagerService.java
// BroadcastReceiver前后台超时
 // How long we allow a receiver to run before giving up on it.
    static final int BROADCAST_FG_TIMEOUT = 10*1000;
    static final int BROADCAST_BG_TIMEOUT = 60*1000;
// 按键分发超时
    // How long we wait until we timeout on key dispatching.
    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
// ContentProvider超时
// How long we wait for an attached process to publish its content providers
    // before we decide it must be hung.
    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;

ActiveServices.java

// Service前后台超时
// How long we wait for a service to finish executing.
    static final int SERVICE_TIMEOUT = 20*1000;
    // How long we wait for a service to finish executing.
    static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;

从发生的原因分:

  1. 主线程有耗时操作,如有复杂的layout布局,IO操作等。
  2. 被Binder对端block
  3. 被子线程同步锁block
  4. Binder被占满导致主线程无法和SystemServer通信
  5. 得不到系统资源(CPU/RAM/IO)

从进程的角度分:

问题出在当前进程:
主线程本身耗时, 或则主线程的消息队列存在耗时操作;
主线程被本进程的其他子线程所blocked;
问题出在远端进程(一般是binder call或socket等通信方式)

ANR分析

  1. Mtklog中搜索anr in,am_anr确定发生组件,原因,时间,CPU使用情况,是否IOWait

典型的分析情况
1.如果TOTAL的和接近100,有可能是因为当前使用的app占用的cpu太高,导致系统将你的杀死。
2.如果TOTAL很小,则说明线程被阻塞了,主线程在等待下条消息的进入,任务在等待时anr。
3.如果ioWait很高,则说明是io操作导致的

  1. traces.txt 中定位

线程中状态

static final Thread.State[] STATE_MAP = new Thread.State[] {
        Thread.State.TERMINATED,     // ZOMBIE
        Thread.State.RUNNABLE,       // RUNNING
        Thread.State.TIMED_WAITING,  // TIMED_WAIT
        Thread.State.BLOCKED,        // MONITOR
        Thread.State.WAITING,        // WAIT
        Thread.State.NEW,            // INITIALIZING
        Thread.State.NEW,            // STARTING
        Thread.State.RUNNABLE,       // NATIVE
        Thread.State.WAITING,        // VMWAIT
        Thread.State.RUNNABLE        // SUSPENDED
    };

native thread有10种状态, 对应着java thread的6种状态.

  1. 如果主线程耗时,状态为TIMED_WAIT
  2. 主线程等待子线程的锁,一定时间出现ANR,状态为MONITOR
    -wait to lock ....held by tid=11 再搜索tid是11的线程信息
上一篇下一篇

猜你喜欢

热点阅读