android app性能优化

各大厂与卡顿和ANR的战斗记录篇

2023-06-12  本文已影响0人  艾瑞败类

作者:Drummor

1.1 认识ANR

1.1.1 系统如何处理ANR

设计原理和影响因素篇,主要对以下关键问题展开

1.1.2 ANR问题分类

把ANR 产生的影响因素清晰的分为了四个大的类别,基本覆盖了ANR问题产生的原因。

系列文章其实就是围绕着这些问题的监控、分析、解决展开的。

2 工具建设-消息调度监控

通过博文得知,今日头条团队,ANR 监控的工具叫 Raster,其最主要的功能就是采集主线程调度。

ANR 产生的原因很多情况下可能是历史耗时问题的累计。因而单纯采集发生ANR 时那一刻的堆栈就会有【堆栈漂移的问题】,也就是采集到的堆栈不是诱发ANR 产生的真正原因。现在ANR 监控的很多框架也是围绕这一问题展开的。

应对方式 对主线程消息调度进行监控记录,包括历史消息,正在执行的消息和将要执行的消息。同时对四大组件执行的消息进行单独的监控,这对我们分析哪个组件产生的ANR 是很重要的参考依据。

这一方案是在网上公开的我能接触到的最早提出的,后面我们会看到很多团队对ANR 问题的监控都是这一方案的变种,或者大同小异。

这一方案的细化,主要包括以下几个方面

2.1 消息聚合

消息统计聚合策略:主线程消息会很多,记录过去5-10秒的消息本身是一个比较重的动作,采用一定的聚合策略是很有必要的。

2.2 每条消息记录的关键信息

2.3 主线程线程堆栈的采样

对耗时的消息,进行采样,采取的策略是超时采样。具体来说,介于大部分的耗时小消息不需要进行堆栈采样,为了避免频繁设置和取消超时任务(也就是采样任务),头条在此处做了一个优化,每次消息开始是并不是重新设置采集超时任务,而是修改目标时间。

3 问题分析&解决

2 微信团队

2021年7月份,微信团队发布在公众号上的两篇文章关于卡顿监控和ANR监控的文章

2.1 首先第一篇《微信Android客户端的卡顿监控方案》

思考这样一个问题,如果我们选择间隔4.5秒去check发送到主线程Looper到Message是否被消费。现在有一个5秒到卡顿,从2秒开始,结束在第7秒耗时5秒,我们间隔5秒能监控到的概率是多少?

答案是只有11%,惊讶不。原因就是在在0-4.5和4.5到9这两个周期内那些空闲的时间,消息都有可能被消费掉!这种情况我们就监控不到了。想想,你再想想,真的是佩服腾讯工程师严谨的工程作风。

2.2 第二篇文章

很是精彩,ANR如何产生,系统源码实现,找监控方案直接一套组合拳,可见功底深厚大佬就是大佬。

其中,通过监听SIGQUIT信号并过滤误报最终监控ANR的方案,也是当前主流的正规方案,为什么是加一个正规的修饰词呢,想想ANRWatchDog那种多不正经就知道这个有多正规。

这里面,几个重要的点我列下

这就是微信团队出的关于Android卡顿和ANR的两篇经典文章,建议大家自信研读,卷起来!

3 钉钉技术团队

2022年12月份,钉钉团队发表的ANR 问题的解决方案系列文章。

3.1 ANR 判定

作为ANR问题不可避免的两个问题

3.2 工具建设

监控ANR 的方案思路与今日头条基本一致,采集主线程的调度信息做记录。其中也有一些不同,把主线程调度的分类,以下五类

可见,其在主线程任务调度的方面监控的更加具体,今日头条的Raster工具从博文看只是对主线程的消息调度进行了监控,我们在结合微信团队的卡顿监控方案,其实可以更全面的对主线程任务进行调度,这一点很知道借鉴学习。

此外,博文里还提出有些手机厂商在应用进程会进入冻结状态,APP 回到前台后才继续执行,冻结的过程里会导致任务耗时过长,需要单独记录,不过这一点今日头条的方案,里能够通过CPUTime 和WallTime 识别出来。

其他方面,ANRCanery 采集也会采集过去当下和等待的任务调度,也对会采集的消息进行聚合处理。堆栈采集上,也是采用了时间对齐方案对堆栈进行采样。

3.3 实践分享

4 其他团队

4.1 阿里其他技术团队

4.1.2 闲鱼团队

2021年6月份, 《关于闲鱼的ANR治理,我有几条心得》

文章短小精悍

3.3 手淘技术团队

《手淘 Android 帧率采集与监控详解》
手淘团队2022年1月份,提出了Android [滑动帧率]思路并给出了比较详细的监控方案。

4.2 shopee 团队

2022年8月份 LooperMonitor

《Android 卡顿与 ANR 的分析实践》

值得注意的点:

4.3 毒物团队

2021年9月份得物团队发表了ANR监控文章

《得物技术 | 得物App ANR监控平台设计》

5 多说一些抓栈问题。

java层面直接通过thread.getStackTrace()获取堆栈信息,是有一定损耗的,对此我们看到大家常规的做法是控制采集的频率,shoppe团队提到的由协程的非堵塞式挂起实现高效的线程堆栈采集,对此我是持怀疑态度

业内确实对高效采集堆栈方向有探索,给出了高效的抓栈方案,妥妥的黑科技看到了比较优秀的两篇供大家参考。

总结

纵观各厂在卡顿和ANR 方面做的探索和方案,我们可以看出,思路上都有重合,在细节方面做了很多针对自身业务和实际情况做的针对性的优化和个性化的开发。总的来说逃不出以下几个步骤

上述ANR 的监控方案,截止到现在都没有开源,卡顿监控在Matrix上开源了。talk is cheap ,因而我在正在尝试取各家之所长,编写开源一个ANR监控工具。目前正在草稿阶段,把基本框架做完之后会尽快开源出来,希望大家参与进来共同建设。关注作者 别错过更新进度。

ANR问题从监控到采集都使用了各种hook手段黑科技,ANR作为Android一种保护机制, 只提出问题,不解决问题的行为都是xxx,目前还未看到官方对此有何动作。

上一篇 下一篇

猜你喜欢

热点阅读