Android 系统(135)---Android anr 分析步骤总结
Android anr 分析步骤总结
前言:最近经手了比较多的anr问题,声明经手不是解决,只是从log上推断造成anr的原因,以此作为根据转交给对应的人来处理。
1. ANR简介
ANR全名Application Not Responding, 也就是"应用无响应". 当操作在一段时间内系统无法处理时, 系统层面会弹出ANR对话框.
通常在如下几种种情况下会弹出ANR对话框:
- 5s内无法响应用户输入事件(例如键盘输入, 触摸屏幕等).
- BroadcastReceiver的事件(onRecieve方法)在规定时间内没处理完(前台广播为10s,后台广播为60s)
- service 前台20s 后台200s未执行完成 Timeout executing service(Android O多了个startForeground 5s限制)
造成以上情况的首要原因就是在主线程(UI线程)里面做了太多的阻塞耗时操作, 例如文件读写, 数据库读写, 网络查询等等.(或者调用Thread.join/LockSupport.park/wait/sleep造成的阻塞)
具体定义:
framework/base/services/core/java/com/android/server/am/ActivityManagerService.java:
- // 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;
- // 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;
- // calling startForeground() before we ANR + stop it.
- static final int SERVICE_START_FOREGROUND_TIMEOUT = 5*1000;
2. ANR分析步骤
anr分析步骤我总结来看主要就如下5步。
2.1 events_log
查看event log确定anr时间点和发生anr的进程id
命令:grep "am_anr.*packageName" ./ -nri --include="events*"
比如:
06-22 23:15:36.257944 942 1021 I am_anr : [0,19721,com.android.chrome,-1463042491,Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 2. Wait queue head age: 5508.0ms.)]
从上面log可以看出是com.android.chrome 在6-22 23:15:36发生了anr,所处进程id为19721
2.2 sys_log
查看sys_log确定当时系统各项占用,虽然我一直对百分比占用很没谱
命令:grep "anr in packageName" ./ -nri --include="sys_log*"
然后vim到对应行
比如:
- 06-22 23:15:42.121724 942 1021 I AnrManager: dumpStackTraces end!
- 06-22 23:15:42.159012 942 1021 I AnrManager: ANR in com.android.chrome (com.android.chrome/com.google.android.apps.chrome.Main), time=24007714
- 06-22 23:15:42.159012 942 1021 I AnrManager: Reason: Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 2. Wait queue head age: 5508.0ms.)
- 06-22 23:15:42.159012 942 1021 I AnrManager: Load: 14.61 / 14.77 / 14.71
- 06-22 23:15:42.159012 942 1021 I AnrManager: Android time :[2018-06-22 23:15:42.12] [24013.623]
- 06-22 23:15:42.159012 942 1021 I AnrManager: CPU usage from 83364ms to 43ms ago (2018-06-22 23:14:12.849 to 2018-06-22 23:15:36.170):
- 06-22 23:15:42.159012 942 1021 I AnrManager: 68% 942/system_server: 50% user + 17% kernel / faults: 267589 minor 3994 major
- 06-22 23:15:42.159012 942 1021 I AnrManager: 21% 1715/com.android.systemui: 16% user + 5.5% kernel / faults: 133310 minor 4496 major
我们可以注意到sys_log时间点晚了不少
2.3 traces.txt
traces.txt主要是来确定下发生anr的时候的堆栈,如果打印出耗时操作的堆栈肯定最好了
发生anr后导出手机里/data/anr下的文件,文件名称一般是这样的“anr_2018-06-22-17-42-44-420”,之前我们通过events_log确定了anr发生时间,这时通过时间找对应文件。
比如上面举的chrome例子:anr_2018-06-22-23-15-36-796 这个文件所对应的时间是差不多的,打开瞅一下。
----- pid 19721 at 2018-06-22 23:15:36 -----
Cmd line: com.android.chrome
前两行 pid 19721对的上,时间时分秒对的上,包名com.android.chrome对的上。
- "main" prio=5 tid=1 Waiting
- | group="main" sCount=1 dsCount=0 flags=1 obj=0x725815f0 self=0xeb15b000
- | sysTid=19721 nice=-4 cgrp=default sched=0/0 handle=0xef2134a4
- | state=S schedstat=( 1948839680 121430176 1126 ) utm=134 stm=60 core=7 HZ=100
- | stack=0xff29c000-0xff29e000 stackSize=8MB
- | held mutexes=
- at java.lang.Object.wait(Native method)
- - waiting on <0x064cfca3> (a java.lang.Object)
- at java.lang.Thread.parkFor$(Thread.java:2137)
- - locked <0x064cfca3> (a java.lang.Object)
- at sun.misc.Unsafe.park(Unsafe.java:358)
- at java.util.concurrent.locks.LockSupport.park(LockSupport.java:190)
- at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:868)
- at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1021)
- at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1328)
- at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:232)
- at org.chromium.components.signin.AccountManagerFacade.getGoogleAccounts(AccountManagerFacade.java:37)
- at org.chromium.components.signin.AccountManagerFacade.tryGetGoogleAccounts(AccountManagerFacade.java:47)
- at org.chromium.components.signin.AccountManagerFacade.tryGetGoogleAccountNames(AccountManagerFacade.java:30)
- at org.chromium.chrome.browser.ChromeTabbedActivity.finishNativeInitialization(ChromeTabbedActivity.java:158)
- at org.chromium.chrome.browser.init.ChromeBrowserInitializer$9.run(ChromeBrowserInitializer.java:3)
- at org.chromium.chrome.browser.init.ChainedTasks$1.run(ChainedTasks.java:7)
- at android.os.Handler.handleCallback(Handler.java:790)
- at android.os.Handler.dispatchMessage(Handler.java:99)
- at android.os.Looper.loop(Looper.java:168)
- at android.app.ActivityThread.main(ActivityThread.java:6555)
- at java.lang.reflect.Method.invoke(Native method)
- at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
- at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857)
从堆栈来看是由于chrome调用getGoogleAccounts继而调用到LockSupport.park-->Object.wait,导致UI线程一直在等待造成anr。(这里其实不严谨,没有直接log作证,万一人家刚wait没多久只是之前一个操作耗时长呢)
由于没有chrome代码,这个故障只好不了了之了,但从堆栈可以看到有可能是哪个模块没有及时调用LockSupport.unpark导致的anr,这样就到应用级别了,需要应用继续往下看。
2.4 main_log
main_log主要是针对应用的log打印的,但有时候追溯问题还是会回到sys_log,主要看是阻塞在应用层还是framework或者native 驱动都说不准。
anr主要是发生在应用的主线程即Ui线程中,那么main_log里搜索对应的 线程号=进程号的log看下。
比如上面的chrome搜索:grep " 19721 19721 " ./ -nr --include="main*"
时间点关注:6-22 23:15:30 - 23:15:36 左右的log,毕竟主要是这5s导致的anr
2.5 综合考虑
其实traces.txt中打印的堆栈有可能是主要原因,有可能是次要原因,也有可能只是个躺枪的,毕竟anr的时间段,就以点击事件anr 5s为例,5s点下去了各个方法都会有耗时,如果一个方法占用了1s,另外一个占用了3s多,最后的一个方法刚开始执行anr就把他堆栈打印出来了那不是很冤。
如果有条件当然是从各种log推断各个方法分别耗时多少,然后综合评判哪个方法可以优化,哪个方法由于外部原因不可避免的耗时延长这都是要看下的。
另外原因也分直接原因和根本原因,比如直接原因是主线程wait了,那根本原因看下是谁让他wait或者谁没及时notify呢。
3. 总结
anr的问题如果traces.txt堆栈打印的很明白,log里也有对应证据,那还是很好的,就怕anr 好几个方法都贡献点延迟,log没有,想调试的话anr一般是monkey中跑出来的,调试难度比较大,那真是欲仙欲死。
Android 系统(135)---Android anr 分析步骤总结相关推荐
- (五十二) Android anr 分析步骤总结
前言:最近经手了比较多的anr问题,声明经手不是解决,只是从log上推断造成anr的原因,以此作为根据转交给对应的人来处理. 1. ANR简介 ANR全名Application Not Respond ...
- 基于Android系统的IPv6网络接入分析
基于Android系统的IPv6网络接入分析 摘 要:本文深入分析了 ...
- 【android系统】android系统升级流程分析(二)---update升级包分析
接下来我们将通过几篇文章来分析update.zip包在具体Android系统升级的过程,来理解Android系统中Recovery模式服务的工作原理.今天让我先来分析下升级包update.zip. 一 ...
- Android系统的JNI原理分析(二)- 数据类型转换和方法签名
声明 前阶段在项目中使用了Android的JNI技术,在此文中做些技术知识总结. 本文参考了一些书籍的若干章节,比如<Android进阶解密-第9章-JNI原理>.<深入理解Andr ...
- 【android系统】android系统升级流程分析(一)---recovery模式中进行update包升级流程分析
今天我们直接来看下android中具体的升级过程是如何的. 升级流程概述 升级的流程图: 升级流程分析 第一步:升级包获取 升级获取可以通过远程下载,也可直接拷贝到指定目录即可. 第二步:准备升级 然 ...
- 基于android系统DVR稳定性问题分析及对策
基于android系统DVR稳定性问题分析及对策 DVR,全名Digital Video Recorder,数字视频录像机,在车载行业大家通俗的叫行车记录仪,因为这个数字视频的内容是行车的形式动态.如 ...
- android log抓取方法,Android系统之Android抓取各种log的方法
Android系统之Android抓取各种log的方法 2018年11月25日 | 萬仟网移动技术 | 我要评论 android之android抓取各种log的方法 1.logcat (四类log b ...
- Android系统架构-[Android取经之路]
摘要:本节主要来讲解Android的系统架构 阅读本文大约需要花费10分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! 欢 ...
- android 服务端技术,移动应用服务器端开发(基于JSP技术)-2017 Android系统构架 Android系统构架.docx...
Android系统构架 PAGE 1 目 录 TOC \o "1-3" \h \z \u 一.Android系统构架 1 二.Linux内核层 2 三.系统运行库层 3 (一)系统 ...
最新文章
- matlab dsp工具箱_GPU中的并行运算,加速你的Matlab程序
- python是干什么用的视频-python基础教程千锋最新视频学完之后可以做什么
- 专业人士提升数据中心职业生涯的6件事
- linux下使用VS CODE + CMAKE 调试C++程序
- 从Xamarin.Essentials谈Xamarin库的封装
- Scrapy源码阅读分析_2_启动流程
- 分页插件PageHelper配置步骤(mybatis)
- git flow 命名规范 驼峰_图解ThinkPHP5框架(一):基础知识,开发规范与目录结构
- 原生JS实现粘贴到剪贴板
- 在本地电脑搭建一个网站 转自本文地址:http://www.fengzimo.com/1503.html 来源 疯子墨...
- C语言中程序设计题 计算机二级考试
- idea打包jar包后java运行jar命令提示jar中没有主清单属性的解决方案
- 计算机指数函数符号,数学公式及符号大全
- 计算机毕业设计之java+SSM酒店客房预定管理系统
- 2021高考自贡成绩查询,多图|自贡2021高考进行时
- 【IoT】STM32 文件系统 fatfs 移植笔记详解
- Mybatis-查询处理一对一和一对多
- SpringBoot总结(六)--连接oracle数据库demo
- 【火炉炼AI】机器学习031-KNN回归器模型的构建
- Python基于PHP+MySQL的个人网页设计与实现