ANR的理论_anr概念/类型/原理/机制

ANR的理论_anr概念/类型/原理/机制ANR 的学习以及分析 anr

大家好,欢迎来到IT知识分享网。

一:什么是anr

ANR(Application Not Responding) 应用程序无响应。如果你应用程序在UI线程被阻塞太长时间,就会出现ANR,通常出现ANR,系统会弹出一个提示提示框,让用户知道。

二:anr 类型

1.KeyDispatchTimeout: input事件在5S内没有处理完成发生了ANR。

logcat日志关键字:Input event dispatching timed out

2.BroadcastTimeout

前台Broadcast:onReceiver在10S内没有处理完成发生ANR。

后台Broadcast:onReceiver在60s内没有处理完成发生ANR。

logcat日志关键字:Timeout of broadcast BroadcastRecord

3. ServiceTimeout

前台Service:onCreate,onStart,onBind等生命周期在20s内没有处理完成发生ANR。

后台Service:onCreate,onStart,onBind等生命周期在200s内没有处理完成发生ANR

logcat日志关键字:Timeout executing service

4.ContentProviderTimeout ContentProvider 在10S内没有处理完成发生ANR。

logcat日志关键字:timeout publishing content providers

ANR的理论_anr概念/类型/原理/机制

三:anr 触发机制

ANR
是一套监控
Android
应用响应是否及时的机制,可以把发生
ANR
比作是引爆炸弹,那么整个流程包含三部分组成:
1. 启动
定时炸弹:中控系统
(system_server
进程
)
启动倒计时,在规定时间内如果目标
(
应用进程
)
没有干完所有的活,则中控系统会定向炸毁(
杀进程
)
目标。
2.
拆炸弹:在规定的时间内干完工地的所有活,并及时向中控系统报告完成,请求解除定时炸弹,则幸免于难。
3.
引爆炸弹:中控系统立即封装现场,抓取快照,搜集目标执行慢的罪证
(traces)
,便于后续的案件侦破
(
调试分析)
,最后是炸毁目标。
举例:用户点击按钮,中控系统启动定时炸弹; 点击按钮后,执行的事务,在规定的5s内完成了,则解除了定时炸弹;如果点击按钮,发现点击按钮做的事务在执行了5s,后还没有结束,然后又有别的输入事件,这个时候,就会引爆炸弹。

service超时机制

ANR的理论_anr概念/类型/原理/机制
1.
客户端
(App
进程
)
向中控系统
(system_server
进程
)
发起启动服务的请求
2.
中控系统派出一名空闲的通信员
(binder_1
线程
)
接收该请求,紧接着向组件管家
(ActivityManager
线程
)
发送消 息,埋下定时炸弹
3.
通讯员
1

(binder_1)
通知工地
(service
所在进程
)
的通信员准备开始干活
4.
通讯员
3

(binder_3)
收到任务后转交给包工头
(main
主线程
)
,加入包工头的任务队列
(MessageQueue)
5.
包工头经过一番努力干完活
(
完成
service
启动的生命周期
)
,然后等待
SharedPreferences(
简称
SP)
的持久化;
6.
包工头在
SP
执行完成后,立刻向中控系统汇报工作已完成
7.
中控系统的通讯员
2

(binder_2)
收到包工头的完工汇报后,立刻去拆除炸弹。如果在炸弹定时结束前拆除炸弹 则拆除炸弹,否则会引发爆炸(
触发
ANR)

broadcast超时机制

对于静态注册的广播在超时检测过程需要检测
SP
,如下图所示
ANR的理论_anr概念/类型/原理/机制
1.
客户端
(App
进程
)
向中控系统
(system_server
进程
)
发起发送广播的请求
2.
中控系统派出一名空闲的通信员
(binder_1)
接收该请求转交给组件管家
(ActivityManager
线程
)
3.
组件管家执行任务
(processNextBroadcast
方法
)
的过程埋下定时炸弹
4.
组件管家通知工地
(receiver
所在进程
)
的通信员准备开始干活
5.
通讯员
3

(binder_3)
收到任务后转交给包工头
(main
主线程
)
,加入包工头的任务队列
(MessageQueue)
6.
包工头经过一番努力干完活
(
完成
receiver
启动的生命周期
)
,发现当前进程还有
SP
正在执行写入文件的操作,便将向中控系统汇报的任务交给SP
工人
(queued-work-looper
线程
)
7. SP
工人历经艰辛终于完成
SP
数据的持久化工作,便可以向中控系统汇报工作完成
8.
中控系统的通讯员
2

(binder_2)
收到包工头的完工汇报后,立刻去拆除炸弹。如果在倒计时结束前拆除炸弹则炸弹拆除,否则会引发爆炸(
触发
ANR)。

SP

8.0
开始采用名叫
“queued-work-looper”

handler
线程,在老版本采用
newSingleThreadExecutor
创 建的单线程的线程池)
如果是动态广播,或者静态广播没有正在执行持久化操作的
SP
任务,则不需要经过
“queued-work-looper”
线程中 转,而是直接向中控系统汇报,流程更为简单,如下图所示:
ANR的理论_anr概念/类型/原理/机制

 provider超时机制

provider
的超时是在
provider
进程
首次启动的时候
才会检测,当
provider
进程已启动的场景,再次请求
provider
并不会触发provider
超时。
ANR的理论_anr概念/类型/原理/机制
1.
客户端
(App
进程
)
向中控系统
(system_server
进程
)
发起获取内容提供者的请求
2.
中控系统派出一名空闲的通信员
(binder_1)
接收该请求,检测到内容提供者尚未启动,则先通过
zygote
孵化新进程
3.
新孵化的
provider
进程向中控系统注册自己的存在
4.
中控系统的通信员
2
号接收到该信息后,向组件管家
(ActivityManager
线程
)
发送消息,埋下炸弹
5.
通信员
2
号通知工地
(provider
进程
)
的通信员准备开始干活
6.
通讯员
4

(binder_4)
收到任务后转交给包工头
(main
主线程
)
,加入包工头的任务队列
(MessageQueue)
7.
包工头经过一番努力干完活
(
完成
provider
的安装工作
)
后向中控系统汇报工作已完成
8.
中控系统的通讯员
3

(binder_3)
收到包工头的完工汇报后,立刻去拆除炸弹。如果在倒计时结束前拆除炸弹则拆除炸弹,否则会引发爆炸(
触发
ANR).

input超时机制

input
的超时检测机制跟
service

broadcast

provider
截然不同,为了更好的理解
input
过程先来介绍两个重要线程的相关工作:
1.InputReader
线程: 负责通过
EventHub(
监听目录
/dev/input)
读取输入事件,一旦监听到输入事件则放入到InputDispatcher的
mInBoundQueue
队列,并通知其处理该事件;
2.InputDispatcher
线程: 负责将接收到的输入事件分发给目标应用窗口,分发过程使用到
3
个事件队列:
   a. 
mInBoundQueue
用于记录
InputReader
发送过来的输入事件;
   b. outBoundQueue
用于记录即将分发给目标应用窗口的输入事件;
   c. waitQueue
用于记录已分发给目标应用,且应用尚未处理完成的输入事件;
input的超时机制并非时间到了一定就会爆炸,而是处理再次有上报输入事件的过程才会去检测是否该爆炸,具体如下图所示。
ANR的理论_anr概念/类型/原理/机制

四:为什么会出现ANR

1:主线程频繁进行耗时的IO操作:如数据库读写

2:多线程操作的死锁,主线程被block;(搜索关键字 held by)

3:主线程被Binder 对端block;

4:System Server中WatchDog出现ANR;

5:service binder的连接达到上线无法和和System Server通信

6:系统资源已耗尽(管道、CPU、IO)

五:ANR 实例分析

主要分析:通过logcat日志或者traces文件确认anr发生时间点; CPU使用率 ;主线程状态;其他线程状态

1,看anr日志,主要了解发生anr的进程等信息

ANR的理论_anr概念/类型/原理/机制ANR的理论_anr概念/类型/原理/机制

2. 看主线程(下面是一个线程死锁的例子)

ANR的理论_anr概念/类型/原理/机制

ANR的理论_anr概念/类型/原理/机制

 主线程执行了耗时操作ANR的理论_anr概念/类型/原理/机制

ANR的理论_anr概念/类型/原理/机制

ANR的理论_anr概念/类型/原理/机制

ANR的理论_anr概念/类型/原理/机制

ANR的理论_anr概念/类型/原理/机制

ANR的理论_anr概念/类型/原理/机制

六,参数分析

ANR的理论_anr概念/类型/原理/机制main:main标识是主线程,如果是线程,那么命名成“Thread-X”的格式,x表示线程id,逐步递增。 prio:线程优先级,默认是5

tid:tid不是线程的id,是线程唯一标识ID

group:是线程组名称

sCount:该线程被挂起的次数

dsCount:是线程被调试器挂起的次数

obj:对象地址

self:该线程Native的地址

sysTid:是线程号(主线程的线程号和进程号相同)

nice:是线程的调度优先级

sched:分别标志了线程的调度策略和优先级

cgrp:调度归属组

handle:线程处理函数的地址。

state:是调度状态

schedstat:从 /proc/[pid]/task/[tid]/schedstat读出,三个值分别表示线程在cpu上执行的时间、线程的等待时间和线程执行的时间片长度,不支持这项信息的三个值都是0; utm:是线程用户态下使用的时间值(单位是jiffies)

stm:是内核态下的调度时间值

core:是最后执行这个线程的cpu核的序号

七:分析步骤

1).收集的信息如下

前台
ANR
发生后,系统会马上去抓取现场的信息,用于调试分析,收集的信息如下
:

a.  将am_anr信息输出到EventLog,也就是说ANR触发的时间点最接近的就是EventLog中输出的am_anr信 息

b. 收集以下重要进程的各个线程调用栈trace信息,保存在data/anr/traces.txt文件

b1. 当前发生
ANR
的进程,
system_server
进程以及所有
persistent
进程
b2. audioserver, cameraserver, mediaserver, surfaceflflinger
等重要的
native
进程
b3. CPU
使用率排名前
5
的进程

c. 将发生ANRreason以及CPU使用情况信息输出到main log

c1. 将
traces
文件和
CPU
使用情况信息保存到
dropbox
,即
data/system/dropbox
目录
c2. 对用户可感知的进程则弹出
ANR
对话框告知用户,对用户不可感知的进程发生
ANR
则直接杀掉

2). 分析步骤

1.
定位发生
ANR
时间点
2.
查看
trace
信息
3.
分析是否有耗时的
message,binder
调用,锁的竞争,
CPU
资源的抢占
4.
结合具体的业务场景的上下文来分析

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/131609.html

(0)
上一篇 2025-08-06 19:10
下一篇 2025-08-06 19:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信