你理解的 ANR 监控可能一直是错的……

news2025/7/20 20:59:08

主要说了几种主流的卡顿监控方式:

  • 通过开一个子线程不断去轮询主线程。原理就是不断向主线程发送Message,每隔一段时间检查一次刚刚发送的消息是否被处理,如果没被处理,说明这段时间主线程被卡住了。

  • 通过使用系统方法 setMessageLogging 替换掉主线程 Looper 的 Printer 对象,通过计算 Printer 打印日志的时间差,来拿到系统 dispatchMessage 方法的执行时间。

  • 通过 Choreographer 类的 FrameCallback 函数。原理当每一帧被渲染时会触发 FrameCallback 回调,FrameCallback 回调 doFrame(long frameTimeNanos) 函数,一次界面渲染会回调 doFrame,如果两次 doFrame 间隔大于16.6ms 则发生了卡顿。

  • 插桩的方式对函数的出入口进行记录。

本篇介绍 ANR 监控,看了一些文章,都是将卡顿阈值设置成 5s 来监控ANR,这其实是很不严谨的,因为 5s 只是 ANR 的一种情况,是 Touch 事件未被及时消费的默认阈值,其他原因的 ANR 阈值并不是 5s。而且就算主线程卡了 5s,input 系统在没有任何事件输入时,也不会 ANR。

那有什么好的方式呢?我们知道当应用 ANR 后,都会 dump 一份 Trace 文件,所以是不是我们只要知道了应用是什么时候生成的这个 Trace 文件,是不是也就知道了ANR 的发生时机呢?

SIGQUIT 信号

当应用发生 ANR 后,system_server 进程会发送 SIGQUIT 信号来通知相关进程来 dump 堆栈,这里就包括发生 ANR 的应用进程(且是第一个收到通知的进程),除此外,还有一些 AMS 维护的 LRU list内的进程(CPU 使用率高的进程)和一些固定的 native 系统进程,也都会收到通知并 dump 堆栈。

微信的 Matrix 库就是运用的这个原理,使用 sigaction 方法注册 signal handler 来监听 SIGQUIT 信号,来达到监控 ANR 的目的,非常巧妙。

我们下面来看看 Matrix,这是入口:

通过 pthread_sigmask 将 SIGQUIT 设置为 UNBLOCK,否则我们的 signal handler 监听不到 SIGQUIT 信号,其会直接被系统的 signal catcher 线程捕获:

创建我们的 signal handler, 并使用 sigaction 方法注册监听:

我们在 handleSignal 方法中收到 SIGQUIT 信号,并设置 anrCallback:

注意当我们使用 Signal Handler 抢了系统的 SIGQUIT,Signal Catcher线程的 sigwait 就收不到信号了,就会导致系统原本的 dump 逻辑没法完成了,所以为了保证系统逻辑不变,我们需要再转发一个 SIGQUIT 信号给到 Signal Catcher:

在 onANRDumped 后,为了防止 SIGQUIT 信号不是由本应用 ANR 导致发出的,需要判断当前进程是否被置了 ProcessErrorStateInfo.NOT_RESPONDING 状态,如果没有,则说明这个信号可能是由其他应用 ANR 导致 system_server 进程发出的。这里会创建了 Check-ANR-State-Thread 线程在 20s 内每隔 500 ms 就轮询查一次:

还有一种情况,当后台ANR 后,并不会设置 NOT_RESPONDING 状态。这里是通过检查主线程 queue#mMessages 的 when 字段,判断当前卡顿的时长,如果发现已卡顿 前台 2s,后台 10s,则认为这是一个 anr,立即上报,防止漏报:

流程就是这个样子了。

还有一点需要思考,我们都知道进程 dump 堆栈后,会将文件保存在 data/anr/ 目录下,这个文件记录非常全,是分析问题的绝佳选择了,可我们没有权限读取怎么办呢?

Matrix 给了解决方法,我们可以通过 hook Signal Catcher 内写 Trace 的 write 方法,来拿到 Trace 内容,具体自行看源码吧。

更多Android 知识点可参考

Android 性能调优系列https://0a.fit/dNHYY

Android 车载学习指南https://0a.fit/jdVoy

Android Framework核心知识点笔记https://0a.fit/acnLL

Android 八大知识体系https://0a.fit/mieWJ

Android 音视频学习笔记https://0a.fit/BzPVh

Android 中高级面试题锦https://0a.fit/YXwVq

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

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

相关文章

ADAU1860调试心得(3)接口说明以及硬件搭建步骤

这个板子是我做的,我做了 3 路模拟输入,1 路模拟输出,我做硬件设计从来就是怎么省事怎么来,所以就直接照着ADI给我的参考设计来的,关键电路坚决不创新,抄就完了。来看看接口的布局情况:三个绿色…

HttpClient别说话,用心看

官网:Apache HttpComponents – Apache HttpComponents 常见使用场景:1.爬虫(python相对做爬虫专业,但是java也可以做) 2.与其他应用进行交互时候 注意下,不同的HttpClient的jar包版本,API和包路径有明显不同 先使用JDK原生API请求网页 将控制台的复制保存为html文件 双击打…

vscode配置自定义代码片段模板

目录1、打开vscode,使用快捷键打开搜索面板2、输入snippets, 点击 代码片段:配置用户代码片段3、模板配置3.1 vue模板配置3.2 全局模板配置1、打开vscode,使用快捷键打开搜索面板 win: Ctrl Shift P mac: command Shift P 2、输入snipp…

圆通山美食城旅游发展总体规划

目 录 目 录 - 1 - 第一章 项目背景及区域概况 - 4 - 一、项目开发背景 - 4 - (一)项目区位 - 4 - (二)自然环境条件 - 4 - 1.气候 - 4 - 2.植被 - 5 - (三)社会经济条件 - 5 - 第二章 SWOT分析 - 6 - 一、…

L16物联网ARM开发--开发环境搭建及平台及GPIO口操作平台介绍(day2、3)

目录 一、MDK-ARM环境介绍及安装 二、STM32Cube简介及安装 STM32CubeMX安装 加载固件库 ​编辑 三、 STM32F0存储器映射 四、STM32启动文件分析 略 五、GPIO的基本概念及寄存器介绍1 1、GPIO接口简介 2、GPIO功能复用 3、GPIO寄存器介绍 GPIO工作原理框图: …

android 签名打包 Invalid keystore format,配置JDK,报错javax.xml.bind.JAXBException

如果AndroidStudio版本高,把Gradle JDK换成更高的版本,就解决了。如下,由1.8换成11,解决了。 这个是全局配置 单独配置项目 File ---> Project Structure---->SDK Location ---> Gradle Srttings jdk配置 MAC 安装JD…

上海亚商投顾:沪指重返3100点 房地产板块掀涨停潮

上海亚商投顾前言:无惧大盘大跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪大小指数今日走势分化,沪指低开后震荡走高,重返3100点上方,以中字头为首的权重股…

Vue3 按需引入 Element Plus

本文记录博主亲测在 Vite 创建的 Vue3 项目框架中从0开始安装配置按需引入 Element Plus 的步骤 注:以下配置的示例为 Vite 构建的 Vue3 脚手架项目 Element UI 官方指南 安装所需插件 请在项目根目录打开终端分别执行如下安装指令: 1.安装 Element …

实时车载激光雷达感知的点云深度学习

又来卷这个了,此次调查了神经网络中使用的计算表示与其性能特征之间的关系,提出了现代深度神经网络中用于3D点云处理的LiDAR点云表示的新计算分类法。使用这种分类法,对不同的方法家族进行结构化分析,论文揭示了在计算效率、内存需…

Resnet的在指静脉识别应用与改进

一、《基于改进残差网络的指静脉识别算法》_易芮 2020.5.20 由于指静脉具有区分性的特征在于其细节特征,为了减少网络训练过程中的信息丢失,在网络中采用改进的大卷积层以及BottleNeck模块. ResNet网络模型采用残差结构和跳跃连接的方式缓解了随着网络的加深而…

web前端-javascript-相等运算符(说明,== 相等运算, != 不相等运算,=== 全等运算,!== 不全等 运算)

文章目录相等运算符1. 说明2. 相等运算2.1. 当使用来比较两个值时,如果值的类型不同,则会自动进行类型转换,将其转换为相同的类型然后再比较2.2. undefined 衍生自 null2.3. NaN 不和任何值相等,包括他本身3. ! 不相等运算4. 全…

【无百度智能云与实体经济“双向奔赴”: 一场1+1>2的双赢 标题】

实体经济,已经成为检验科技企业潜力的试金石。 在最近的财报季中,各家大厂的财报里“实体经济”都是关键字眼,已经成为各家心照不宣的共同目的地。 当然,条条大路通罗马。每一家的战略思路和打法都不一样。11月22日,…

数据结构题目收录(二十四)

1、在将序列(6,1,5,9,8,4,7)建成大根堆时,正确的序列变化过程是()。 A:6,1,7,9,8,4,5->6,9,7,1,8,4,5->9,6,7,1,8,4,5->9,8,7,1,6,4,5B:6,9,5,1,8,4,7->6,9,7,1,8,4,5->9,6,7,1,8,4,5->9,8,7,1,6,4…

【TUN模式】对QQ或者微信域名相关的网站访问非常慢、图片加载不出来、网页空白的解决方案

一、问题背景 最近在电脑上登录微信时,或者浏览微信公众号的文章时,经常出现卡顿得出不来图片的情况,即使出来了也是排版异常。 二、研究现状(哈哈哈哈科研人的写作习惯?) 目前网上有些大咖对这个问…

qt 实现PDF阅读器

1、前言 查阅资料可发现,网上的几种pdf阅读器的实现,几乎大多依赖的第三方库,这里就不做介绍了。 qt 自带的关于pdf的显示:pdfwriter、printpreviewwidget,分别为创建pdf 和 打印预览pdf。由此,后者似乎满足…

快速上手Python命令行模块Click

关于Click? 说下 Click 模块是干啥的,简单说,它就是把我们的 Python 脚本的一些函数,通过 添加带有 Click 关键字的装饰器进行装饰进而将函数调用的形式转化为命令行传参的形式然后执行。听不懂也没关系,我们会一步一步来&#x…

【OpenGL开发】VS2017+nuget配置OpenGL开发环境

文章目录1、简介1.1 先决条件1.2 查找并安装包1.3 卸载软件包1.4 更新包1.5 管理解决方案的包1.6 “合并”选项卡2、nuget配置程序源2.1 在线源2.2 本地源3、nuget安装库3.1 nuget安装nupengl.core(C)3.2 nuget安装Giawa.OpenGL(C#&#xff0…

听音乐赚钱App,每天听歌收益5美金,保姆级教学,被动收入人人可做

文章目录调研操作变现链接调研 今天分享的就是一个无门槛挂机项目。不需要科学上网,只要听歌就能赚钱。 首先我们需要先认识平台,这个平台叫做current。 是一个听音乐赚积分的平台,它这个赚钱逻辑也非常简单,在平台听歌就可以获取积分,不过最后是可以用积分兑换美金的。官方的说…

索辰科技在科创板过会:拟募资金额有所下调,上半年亏损4000万元

11月24日,上海证券交易所科创板披露的信息显示,上海索辰信息科技股份有限公司(下称“索辰科技”)获得上市委会议通过。据贝多财经了解,索辰科技于2022年6月29日递交招股书,准备在科创板上市。 据了解&#…

Word处理控件Aspose.Words功能演示:在 Python 中将 Word 文档转换为 PNG、JPEG 或 BMP

MS Word 文件到图像格式的转换让您可以将文档的页面嵌入到您的 Web 或桌面应用程序中。为了在 Python 应用程序中执行此转换,本文介绍了如何使用 Python 将 Word DOCX或DOC文件转换为PNG、JPEG或BMP图像。此外,您将学习如何使用不同的选项控制 Word 到图…