如何应对 Android 面试官 -> ANR 如何优化?线上 ANR 如何监控?

前言


在这里插入图片描述

本章主要围绕 ANR 如何监控以及优化;

基本概念


ANR(Android Not Responding) 是指应用程序未响应,Android 系统对于一些事件需要在一定的时间范围内完成,如果超过预订时间未能得到有效响应或者响应时间过长,都会造成 ANR。

ANR 常见类型


input 事件

input事件在5s内没有处理完;

  • logcat关键字:input event dispatching timed out;
  • tag:对于input来说,即便某次事件执行时长超过了timeout时长,只要后续没有再生成输入事件,则不会发生anr;

Input 的超时机制与其他不同,对于 input 事件来说即便某次事件执行时间超过了 timeout 时长,只要用户后续再没有生成输入事件,则不会触发 ANR;

broadcast事件

  • 前台广播:10s内没有处理完;
  • 后台广播:60s内没有处理完;

logcat关键字:timeout of broadcast BroadcastRecord

service事件

  • 前台service:20s内没有处理完;
  • 后台service:200s内没有处理完;

logcat关键字:timeout executing service;

provider 事件

10s内没有处理完;

logcat关键字:timeout publishing content provider;

ANR 出现的原因


  • 主线程进行耗时的 IO 操作;
    • 例如数据库读写
    • 网络操作
    • 序列化
    • 文件读写
    • sp 操作
  • 多线程操作的死锁,导致主线程被block;
    • traces.txt中的关键字:held mutexes / held by
  • 系统资源被耗尽(管道 CPU IO);
  • 主线程被 binder,对端 block;
    • binder 通信默认是同步的,也可以异步实现,如果同步通信的时候,如果对端被 block 之后,导致主端就会无限等待;
  • System Server 中的 WatchDog 出现 anr;
  • Service binder 的连接达到上限,无法和 System Server 通信;

ANR 问题如何解决


发生 anr 之后 会在 /data/anr/trace_*.txt 生成这么一个文件;

如何分析这个 trace 文件;

  • 发生 anr 之后,一般是 firstPid,即发生 anr 的 Pid;
  • 线下发生 anr 的时候,通过 logcat 日志,traces 文件确认 anr 发生时间点,traces 文件和 cpu 使用率;
  • traces 文件分析
    • ANR 时间
    • 当前应用进程 id
    • 当前应用的进程名
    • ANR类型:KeyDispatchTimeout
    • held by、mutexes 关键字
    • 关注线程状态
      在这里插入图片描述

ANR 如何进行线上监控的原理


FileObserver

Android 系统提供了一个 抽象类 FileObserver,我们可以通过它来监控 data/anr/traces_xxx.txt 文件的变化,用来监控某个目录/文件 状态发生改变,有没有创建或者删除文件;

public class ANRFileObserver extends FileObserver {public ANRFileObserver(String path) { //data/anr/super(path);}public ANRFileObserver(String path, int mask) {super(path, mask);}@Overridepublic void onEvent(int event, @Nullable String path) {switch (event){case FileObserver.ACCESS://文件被访问Log.i("TAG", "ACCESS: " + path);break;case FileObserver.ATTRIB://文件属性被修改,如 chmod、chown、touch 等Log.i("TAG", "ATTRIB: " + path);break;case FileObserver.CLOSE_NOWRITE://不可写文件被 closeLog.i("TAG", "CLOSE_NOWRITE: " + path);break;case FileObserver.CLOSE_WRITE://可写文件被 closeLog.i("TAG", "CLOSE_WRITE: " + path);break;case FileObserver.CREATE://创建新文件Log.i("TAG", "CREATE: " + path);break;case FileObserver.DELETE:// 文件被删除,如 rmLog.i("TAG", "DELETE: " + path);break;case FileObserver.DELETE_SELF:// 自删除,即一个可执行文件在执行时删除自己Log.i("TAG", "DELETE_SELF: " + path);break;case FileObserver.MODIFY://文件被修改Log.i("TAG", "MODIFY: " + path);break;case FileObserver.MOVE_SELF://自移动,即一个可执行文件在执行时移动自己Log.i("Zero", "MOVE_SELF: " + path);break;case FileObserver.MOVED_FROM://文件被移走,如 mvLog.i("TAG", "MOVED_FROM: " + path);break;case FileObserver.MOVED_TO://文件被移来,如 mv、cpLog.i("TAG", "MOVED_TO: " + path);break;case FileObserver.OPEN://文件被 openLog.i("TAG", "OPEN: " + path);break;default://CLOSE:文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)//ALL_EVENTS:包括上面的所有事件Log.i("TAG", "DEFAULT(" + event + "): " + path);break;}}
}

ANR WatchDog

系统源码中『看门狗』的实现:监控 System Server 中的 AMS 有没有死锁,某个线程有没有被卡住;

在这里插入图片描述

参考 Watchdog 的监控方案;

在这里插入图片描述

public class ANRWatchDog extends Thread {private static final String TAG = "ANR";private int timeout = 5000;private boolean ignoreDebugger = true;static ANRWatchDog sWatchdog;private Handler mainHandler = new Handler(Looper.getMainLooper());private class ANRChecker implements Runnable {private boolean mCompleted;private long mStartTime;private long executeTime = SystemClock.uptimeMillis();@Overridepublic void run() {synchronized (ANRWatchDog.this) {mCompleted = true;executeTime = SystemClock.uptimeMillis();}}void schedule() {mCompleted = false;mStartTime = SystemClock.uptimeMillis();mainHandler.postAtFrontOfQueue(this);}boolean isBlocked() {return !mCompleted || executeTime - mStartTime >= 5000;}}public interface ANRListener {void onAnrHappened(String stackTraceInfo);}private ANRChecker anrChecker = new ANRChecker();private ANRListener anrListener;public void addANRListener(ANRListener listener){this.anrListener = listener;}public static ANRWatchDog getInstance(){if(sWatchdog == null){sWatchdog = new ANRWatchDog();}return sWatchdog;}private ANRWatchDog(){super("ANR-WatchDog-Thread");}@TargetApi(Build.VERSION_CODES.JELLY_BEAN)@Overridepublic void run() {Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); // 设置为后台线程while(true){while (!isInterrupted()) {synchronized (this) {anrChecker.schedule();long waitTime = timeout;long start = SystemClock.uptimeMillis();while (waitTime > 0) {try {wait(waitTime);} catch (InterruptedException e) {Log.w(TAG, e.toString());}// 防止假唤醒waitTime = timeout - (SystemClock.uptimeMillis() - start);}if (!anrChecker.isBlocked()) {continue;}}if (!ignoreDebugger && Debug.isDebuggerConnected()) {continue;}String stackTraceInfo = getStackTraceInfo();if (anrListener != null) {anrListener.onAnrHappened(stackTraceInfo);}}anrListener = null;}}private String getStackTraceInfo() {StringBuilder stringBuilder = new StringBuilder();for (StackTraceElement stackTraceElement : Looper.getMainLooper().getThread().getStackTrace()) {stringBuilder.append(stackTraceElement.toString()).append("\r\n");}return stringBuilder.toString();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/453295.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP_MM模块-设置业务合作伙伴类型字段必输(多种方案)

一、业务背景 公司需要把供应商增加一个细分的维度,并且要求该字段设置为必输,防止用户新增供应商时忘记维护。这里给用户找了一个分类的字段:业务合作伙伴类型,本文主要讲解如何设置该字段设置为必填; 注意&#xff…

[笔记] 关于CreateProcessWithLogonW函数创建进程

函数介绍 https://learn.microsoft.com/zh-cn/windows/win32/api/winbase/nf-winbase-createprocesswithlogonw BOOL CreateProcessWithLogonW([in] LPCWSTR lpUsername,[in, optional] LPCWSTR lpDomain,[in] …

【MySQL】表的约束、基本查询、内置函数

目录 1. 表的约束1.1 空属性1.2 默认值1.3 列描述1.4 zerofill1.5 主键1.6 自增长1.7 唯一键1.8 外键 2. 基本查询2.1 表的增删改查2.1.1 插入数据2.1.2 插入否则更新2.1.3 替换插入 2.2 Retrieve2.2.1 select ----- 查询2.2.2 where ----- 筛选2.2.3 order by ----- 结果排序2…

C++11——基础新增特性

目录 C11介绍统一的列表初始化对内置类型initializer_list 声明autodecltypenullptr 范围for容器新增接口emplace容器的新方法 C的前身是“C with Classes”, 最早于 1979年由 祖师爷Bjarne Stroustrup(本贾尼斯特劳斯特鲁普) 在贝尔实验室…

#HarmonyOS:页面和自定义组件生命周期

页面生命周期 即被Entry装饰的组件生命周期 onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。onPageHide: 页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。onBackPress: 当用户点击返回按钮是触发 组件…

成都睿明智科技有限公司解锁抖音电商新蓝海

在这个短视频风靡的时代,抖音已不仅仅是一个娱乐平台,它更是商家们竞相追逐的电商新战场。成都睿明智科技有限公司,作为抖音电商服务领域的佼佼者,正以敏锐的洞察力和专业的服务,助力众多品牌在这片蓝海中乘风破浪&…

RHCE-多IP访问网站

关闭防火墙 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0下载nginx工具 [rootlocalhost ~]# yum install nginx Updating Subscription Management repositories. Unable to read consumer identityThis system is not registered with an …

面对AI算力需求激增,如何守护数据中心机房安全?

随着人工智能(AI)技术飞速发展,AI算力需求呈现爆发式增长,导致对数据设备电力的需求指数级攀升。这给数据中心带来前所未有的挑战和机遇,从提供稳定的电力供应、优化高密度的部署,到数据安全的隐私保护&…

【unity小技巧】Unity6 LTS版本安装和一些修改和新功能使用介绍

文章目录 前言安装新功能变化1、官方推荐使用inputsystem进行输入控制2、修复了InputSystem命名错误导致listen被遮挡的bug3、自带去除unity启动画面logo功能4、unity官方的behavior行为树插件5、linearVelocity代替过时的velocity方法待续 完结 前言 2024/10/17其实unity就已…

前端拦截302重定向

背景: 根据业务场景需要拦截302做后续的逻辑处理 尝试一: : axios拦截 、、、、、async created() {// 获取302请求返回的location后手动修改video的src路径let targetSrc;try {await axios.get(this.video).then((res) > {const { headers, status } res;const { locat…

Spring Cloud 解决了哪些问题?

大家好,我是锋哥。今天分享关于【Spring Cloud 解决了哪些问题?】面试题?希望对大家有帮助; Spring Cloud 解决了哪些问题? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Cloud 是一个为构建分布式…

如何删除Maven

1.找到Maven安装路径 方法一: 可以直接在文件资源管理器里面选中“此电脑”然后右上角搜“apache-maven”,这个过程可能长达几分钟甚至更久 方法二: 这里推荐一个名叫“Everything”的软件,能够快速的查找到需要的文件 2.找到本…

每日一道算法题(Leetcode 20)

Whats past is prologue. 凡是过去,皆为序章。 题目 分析 1. 我们可以用栈的结构来解决这道题。 2. 我们使用while循环,每次读取字符串中一个元素进行操作,直到最后读取到 \0为止。 3. 如果遇见 (, [ ,{ 这三种左括号,则把该左…

【AIGC】AI如何匹配RAG知识库:关键词搜索

关键词搜索 引言jieba库简介TF-IDF简介实践例子用jieba库提取关键词计算TF-IDF计算文档和查询相似度结果完整代码: 总结 引言 RAG作为减少模型幻觉和让模型分析、回答私域相关知识最简单高效的方式,我们除了使用之外可以尝试了解其是如何实现的。在实现…

写一个自动采集地球前30行业的小程序

创建一个自动采集地球前30行业信息的小程序可以使用Python和一些常用的库,如BeautifulSoup和Requests。以下是一个基本示例,展示如何从网页上抓取行业信息: 环境准备 安装Python:确保你的计算机上已安装Python。安装库&#xff…

电影评论网站开发:Spring Boot技术指南

3系统分析 3.1可行性分析 通过对本电影评论网站实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本电影评论网站采用SSM框架,JAVA作为开发语言&#…

从传统到智能,从被动监控到主动预警,解锁视频安防平台EasyCVR视频监控智能化升级的关键密钥

视频监控技术从传统监控到智能化升级的过程是一个技术革新和应用场景拓展的过程。智能视频监控系统通过集成AI和机器学习算法,能够实现行为分析、人脸识别和异常事件检测等功能,提升了监控的准确性和响应速度。这些系统不仅用于传统的安全防护&#xff0…

【linux009】文件操作命令篇 - touch 命令

文章目录 touch 命令1、基本用法2、常见选项3、举例4、注意事项 touch 命令 touch 是 Linux 系统中的一个常用命令,用于创建空文件或更新已有文件的时间戳。它既可以用来快速生成新文件,也可以用来修改文件的访问时间(access time, atime&am…

react18中如何监听localstorage的变化获取最新的本地缓存

有时候业务中会需要监听缓存的变化,实时更新页面的内容获取发送接口请求。这就要我们来监听对localstorage的修改,实时响应变化!!一下方法同样实用于vue项目。 同一个项目中不同页面的实现 实现效果 代码分析 修改localstoare的…

【算法】KMP算法

写在前面 在学习KMP算法前,不才也曾在众多博客中阅读过KMP算法的文章,但是都看得迷迷糊糊,所以不才在学透了KMP算法后,详细编写了这篇笔记,希望对你有帮助🥰🥰。 KMP算法的核心思想不分任何语…