前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ANR问题的定位与分析

ANR问题的定位与分析

作者头像
用户5521279
发布2020-03-19 15:57:33
2.7K0
发布2020-03-19 15:57:33
举报
文章被收录于专栏:搜狗测试搜狗测试
【前言】

ANR问题,相信是日常应用测试中,各位小伙伴都会遇到的问题。本篇对ANR的类型、原因及出现场景、以及ANR定位与分析思路进行了总结!

【一. ANR定义与分类】

ANR定义

ANR全称Application Not Responding,意思就是程序未响应。如果应用程序在UI线程被阻塞太长时间,就会出现ANR。出现ANR,通常系统会弹出一个提示提示框。

ANR类型

(1). 广播ANR

(2). ServiceANR

(3). ContentProviderANR

(4). InputANR

(5). 系统WatchDog

ANR超时阈值

不同组件的超时阈值不同,Service、Broadcast、ContentProvider 、Input的超时阈值如下

(1)BroadcastTimeout

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

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

(2)ServiceTimeout

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

后台Service:onCreate,onStart,onBind等生命周期在200s内没有处理完成发生ANR (3)ContentProviderTimeout ContentProvider 在10S内没有处理完成发生ANR。

(4)KeyDispatchTimeout

input事件在5S内没有处理完成(如按键或者触摸)发生了ANR。

【二. ANR产生原因与出现场景】

1. 产生ANR原因

a. 耗时操作

b. 自身服务阻塞

c. 系统阻塞

d. 内存紧张

e. CPU资源抢占

2. 典型场景

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

b. 多线程操作的死锁,主线程被block;

c. 主线程被Binder 对端block;

d. SystemServer中WatchDog出现ANR;

e. servicebinder的连接达到上限无法和和System Server通信

f. 系统资源已耗尽(管道、CPU、IO)

【三. ANR定位与分析】

1. ANR分析思路——traces

通常发生ANR时,首先去查找对应Trace(重要进程的各个线程调用栈trace信息)日志,看看主线程是否在处理该广播或被阻塞。

trace路径:/data/anr/traces.txt

trace导出:adb pull/data/anr/traces.txt

最新的ANR信息在最开始部分,我们从stacktrace中即可找到出问题的具体行数。

在文件中使用ctrl + F 查找包名可以快速定位相关代码。特别注意:产生新的ANR,原来的 traces.txt 文件会被覆盖。

2. ANR其他分析思路与相关日志

如果发现堆栈完全处于空闲状态,那就需要结合log日志进行分析,包括logcat、kernel日志、cpuinfo以及meminfo等,参考顺序从前向后。

分析logcat思路

首先在日志中搜索(“anrin”,“low_memory”,“slow_operation”)等关键字,通过该类关键字主要是查看系统CPU负载,如果是发现应用进程CPU明显过高,那么很有可能是该进程抢占CPU过多导致,系统调度不及时,误认为应用发生了超时行为。

分析kernel思路

在此类日志中直接搜索lowmemorykiller,如果存在则查看发生时间和ANR时间是否大致对应,相差无几的话,可以从该日志中看到操作系统层面当前内存情况,Free Memory说明的是空闲物理内存,File Free说明的则是文件Cache,也就是应用或系统从硬盘读取文件,使用结束后,kernel并没有这正释放这类内存,加以缓存,目的是为了下次读写过程加快速度。当然,发现Free和Other整体数值都偏低时,Kernel会进行一定程度的内存交换,导致整个系统卡顿。同时这类现象也会体现在log日志“slow_operation”中,即系统进程的调度也会收到影响。

分析cpuinfo思路

这类日志,可以清晰的看到哪类进程CPU偏高,如果存在明显偏高进程,那么ANR和此进程抢占CPU有一定关系。当然,如发现Kswapd,emmc进程在top中,则说明遇到系统内存压力或文件IO开销。

分析meminfo思路

分析该类日志,主要是看哪类应用或系统占用内存偏高,如果应用内存占用比较正常,系统也没有发生过度内存使用,那么则说明系统中缓存了大量进程,并没有及时释放导致系统整体内存偏低。

3. traces.txt重要字段

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核的序号。

找到java的堆栈信息定位代码位置,定位到问题。

【四. ANR分析案例】

分析案例一:Input ANR

分析案例二:在系统的方法上的锁没释放

WindowManagerGlobal.dumpGfxInfo

Blocked就一定有被持有的对象,这个有时候是发生在binder,就需要分析binder相关的log

分析案例三 内存问题

分析案例四 GC问题

观察Trace主线程堆栈,发现主线程在申请内存过程中被block,等待GC结束,

再看看其它线程状态,进一步查找发现,下面任务正在执行GC

Tid=8线程执行GC,导致主线程申请内存被Block,应用进程内存使用不当,导致GC时间过程,产生ANR。

【参考】

https://juejin.im/post/5be698d4e51d452acb74ea4c

https://www.jianshu.com/p/862ce91c1abf

https://droidyue.com/blog/2015/07/18/anr-in-android/

https://www.jianshu.com/p/388166988cef

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 搜狗测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ANR超时阈值
  • 2. 典型场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档