ANR总结

作者: 小的橘子 | 来源:发表于2019-03-17 16:34 被阅读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的线程信息

    相关文章

      网友评论

          本文标题:ANR总结

          本文链接:https://www.haomeiwen.com/subject/hkoymqtx.html