如何应对 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.mzph.cn/bicheng/57228.shtml

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

相关文章

91 VRRP负载局衡+主备切块 V2

实操四 负载均衡主备 VRRP(虚拟路由冗余协议)是一种网络协议,用于提高网络的可用性和冗余性。VRRP可以将多个路由设备组成一个虚拟路由器,当主路由设备故障时,自动切换到备用路由设备,从而实现高可用性。 …

Mamba学习笔记(2)—序列数据处理基础

文章目录 (1) RNN(Recurrent Neural Networks)基本原理代码定义 (2) SLTM (Long Short-Term Memory)基本原理代码定义 (3) GRU (Gated Recurrent Unit)基本原理代码定义 (4) Transformer(☆☆☆Attention Is All You Need☆☆☆)0…

OpenCloud7.9 安装docker

错误代码 failure: repodata/repomd.xml from docker-main-repo: [Errno 256] No more mirrors to try. http://mirrors.aliyun.com/docker-engine/yum/repo/main/centos/2/repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found 解决步骤: 1. 删除或禁用错…

【数据价值化】数据资产价值实现:入表、交易、融资和代运营

在当今数字化时代,数据已经成为企业最宝贵的资源之一。如何有效管理和利用数据资产,实现数据价值最大化,已成为众多企业面临的重要课题。本文将深入探讨实现数据资产价值的四种主要方式:入表、交易、融资和代运营。通过剖析这四种方式的内涵、流程、关键点以及优势和挑战,为企业…

vue前端开发框架的常见知识点和应用

Vue.js 是一个渐进式的前端框架,用于构建用户界面和单页面应用程序(SPA)。在开发过程中,有一些常见的知识点和应用场景非常重要。下面是对Vue.js的主要知识点和应用的详细说明: 一、基础知识点 1. Vue实例 Vue实例是…

nginx解决非人类使用http打开的443,解决网安漏扫时误扫443端口带来的问题

一、问题描述 正常访问https的站点时,使用网址https://www.baidu.com,但会有一种错误的访问请求http://www.baidu.com:443,一般都是非人类所为,如漏洞扫描工具,那么请求以后带来的后果是个错误页面 400 Bad Request T…

如何选择合适业务协作平台?—— 板栗看板给你答案

在当今快速发展的商业环境中,团队协作和项目管理变得越来越重要。业务协作平台作为一种工具,可以帮助团队成员进行有效的沟通、任务分配和进度跟踪。这些平台通常具备项目管理、文档共享、实时通讯等功能,以提高团队的工作效率和协作能力。 一…

AttributeError: ‘function‘ object has no attribute ‘decode‘

h5py版本过高&#xff0c;降低版本即可。 1.卸载h5py pip uninstall h5py 卸载后&#xff0c;查看h5py版本&#xff0c;显示这个代表卸载成功。 import h5py print(h5py.__version__) 2. 安装低版本的h5py<3.0.0 目前的版本有&#xff1a; 2.2.1, 2.3.0b1, 2.3.0, 2.3.1,…

如何看ip属于什么地址

在数字化时代&#xff0c;IP地址作为互联网通信的基石&#xff0c;扮演着至关重要的角色。无论是网络管理、安全防护&#xff0c;还是日常的网络访问&#xff0c;理解IP地址的性质和分类都是必不可少的技能。本文将深入探讨如何判断一个IP地址属于哪一类地址&#xff0c;并详细…

阿里云验证码短信发送服务搭建(flask)

参考&#xff1a;https://next.api.aliyun.com/api-tools/sdk/Dysmsapi?version2017-05-25&languagejava-async-tea&tabprimer-doc 我们需要思考验证服务一些要求&#xff1a; 1.验证码只能被验证一次&#xff0c;所以需要状态字段 2.验证码有失效时间&#xff0c;超…

内存屏障的奥秘:深入理解并掌握Java并发编程的底层优化

1. 什么是内存屏障&#xff08;Memory Barrier&#xff09;&#xff1f; 内存屏障&#xff08;Memory Barrier&#xff09;&#xff0c;也称为内存栅栏&#xff0c;是一种硬件级别的指令&#xff0c;用于控制CPU和编译器的指令重排序。它确保特定操作在多线程编程环境中不会被…

C++STL--------list

文章目录 一、list链表的使用1、迭代器2、头插、头删3、insert任意位置插入4、erase任意位置删除5、push_back 和 pop_back()6、emplace_back尾插7、swap交换链表8、reverse逆置9、merge归并10、unique去重11、remove删除指定的值12、splice把一个链表的结点转移个另一个链表13…

利用Spring Boot实现信息化教学平台

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理信息化在线教学平台的相关信息成为必然。开…

Python基础和理论学习

Python作为一种高级编程语言&#xff0c;以其简洁的语法和广泛的应用&#xff0c;成为许多开发者和分析师首选的语言。无论是用来进行数据分析、机器学习、Web开发还是自动化任务&#xff0c;Python都具有强大的功能。本文将深入探讨Python的基础知识和理论&#xff0c;以帮助你…

AI金融攻防赛:YOLO理论学习及赛题进阶思路(DataWhale组队学习)

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年10月学习赛的AI金融攻防赛学习总结文档。本文主要讲解如何在金融场景凭证篡改检测中应用YOLO算法。我们将从模型概述、数据准备、训练流程以及模…

互联网数字化商品管理浪潮思考:从信息化到精准运营

目录 一、商品数字化转型面临的现状分析 &#xff08;一&#xff09;运营方向分析 &#xff08;二&#xff09;商品归类分析 二、商品数字化管理建设分析 三、基础建设——商品信息数字化 &#xff08;一&#xff09;商品信息质量数字化的目的 &#xff08;二&#xff0…

Apache HTTP服务器上强制执行HTTPS重定向

要在Apache HTTP服务器上强制执行HTTPS重定向&#xff0c;您可以在服务器配置的虚拟主机中使用Redirect指令或者RewriteRule。以下是两种常见的方法&#xff1a; 方法1&#xff1a;使用Redirect指令 <VirtualHost *:80>ServerName yourdomain.comRedirect / https://yo…

[k8s理论知识]3.docker基础(二)隔离技术

容器其实是一种沙盒技术&#xff0c;其核心是通过约束和修改进程的动态表现&#xff0c;为其创建一个边界。这个边界确保了应用与应用之间不会相互干扰&#xff0c;同时可以方便在不同的环境中迁移&#xff0c;这是PaaS最理想的状态。 程序是代码的可执行镜像&#xff0c;通常…

力扣1652.拆炸弹

你有一个炸弹需要拆除&#xff0c;时间紧迫&#xff01;你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。 为了获得正确的密码&#xff0c;你需要替换掉每一个数字。所有数字会 同时 被替换。 如果 k > 0 &#xff0c;将第 i 个数字用 接下来 k 个数字之…

探索Spring Cloud Config:构建高可用的配置中心

目录 认识Spring Cloud ConfigConfig Server读取配置文件步骤1&#xff1a;&#xff08;1&#xff09;创建config-server项目&#xff08;2&#xff09;在config-server中开启Config Server功能&#xff08;3&#xff09;在config-server配置文件进行相关配置&#xff08;4&…