Android稳定性方案浅析
定义: 这里的Android稳定性单指Crash
指标口径: 用户可感知崩溃率,以用户为纬度,即Crash设备数 / 总设备数
精细化单个bug的纬度:
- bug频次
- 爆炸半径
- 影响时长
从崩溃的发生解决整个链路出发: RD编码 --> 线下测试 --> 灰度发版 --> 崩溃发生&数据采集聚类 --> RD修复 --> 版本发布
整体思路
1、编码阶段
制定代码规范,加强代码Review,引入静态代码检查,完善测试流程等减少问题发生
a、静态代码检查
有时会出现某些低级错误如:divide by zero 导致的crash,使用Lint和detekt进行静态代码检查不失为一种好方案,可以放在代码合入的SA阶段
b、查看是否需要解决警告问题
在我们编码或者改动历史遗留的代码时,AS中存在一些警告⚠️,commit时要根据提示进行review,是否需要每次修复和改动还有待商榷
c、检测SQL质量
参考Matrix SQLite Lint: 按官方最佳实践自动化检测 SQLite 语句的使用质量;(看能否拓展到其他场景)
d、依赖库的检查 (可以跟组件化相关)
采用gradle脚本编译时检查依赖库是否相同,解决不同组件或者不同APP之间SDK版本不一致可能导致的崩溃,避免CI阶段打包失败或者上线后出现异常
- 新增or改动SDK检测,CI diff 产出依赖树 全功能提测阶段
e、review规范
- 提交reviewer的质量把控意识;关键代码需要两个人review,+1 +2通过才可以合入
- 跟流水线CI自动识别核心类文件要求两人review的能力结合起来
2、测试&流水线
提高稳定性的意识,不管多微小的改动都要进行自测!!!
a.单元测试
- 重点模块的单测能力
b.自动化测试
- 结合QA补齐自动化测试的能力,覆盖核心场景
- 跟devops平台能力结合,将LeakCanary等能力跟Monkey结合,自动创建卡片
- 针对函数接口的异常数据排雷测试(参考juejin.cn/post/702812…)
c.CI/CD
- 流水线打包效率提升
3、崩溃数据采集&分析
正如RD讲的那样,给我一个崩溃堆栈我就能定位到问题所在,能完整的还原"事故现场"成为重中之重
a.堆栈反混淆
结合各个公司APM平台上传mapping文件以及符号表,每个崩溃数据均展示混淆之前的定位
b.平台堆栈聚类
c.平台数据状态标识
已修复、Pending、下个版本修复等状态或者备注的标识,每次分析结果留下文字记录
d.分模块上传关键数据
会员模块上传会员信息、支付模块上传订单信息等
4、灰度阶段
a.测试轨道前置小版本提前暴露问题
b.三方SDK降级策略
firebase、广告库等三方SDK升级一定要观察崩溃率变化,并做好降级处理
c.crash率异常熔断机制
- 灰度过程缺少中间对Crash率异常的评定标准,业务异常的评定标准
- 整体&每个崩溃数据的量级(该崩溃人数/安装率)记录,设定阈值,每日将两个版本对比骤增或者骤降的数据输出并产出报告
c.上车策略
核心思路是代码改动最小化,预留todo下迭代改,避免造成新的线上crash
5、重点问题解决
I.源码分析
虽然 androidxref.com 和 cs.android.com 都可以在线查阅源码,但这两处的Android版本并不全;android.googlesource.com 这里可以下载到几乎所有版本的源码,本地通过 Sublime 分析源码也十分方便(可以直接显示和跳转到方法的定义&引用位置)。
II.OOM问题
a.大图监控治理
- 线下监控:通过插件在 mergeResources 任务后,遍历图片资源,搜集超过阈值的图片资源,输出列表
- 参考NativeBitmap 把应用内存使用的大头(即 Bitmap 的像素占用的内存)转移到 Native 堆;但是可能会导致32位虚拟内存不足
- 在接口层中将所有被创建出来的 Bitmap 加入一个 WeakHashMap,同时记录创建 Bitmap 的时间、堆栈等信息,然后在适当的时候查看这个 WeakHashMap 看看哪些 Bitmap 仍然存活来判断是否出现 Bitmap 滥用或泄漏。 微信 Android 终端内存优化实践
b.hook pthred
采用bhook,针对pthread_create创建的子线程中发生了信号(SIGSEGV)进行兜底操作;相当于catch native crash,发生crash时重新执行之前的逻辑
c.32位虚拟内存优化
- Patrons 通过一系列技术手段实现运行期间动态调整
Region Space
预分配的地址空间 - mSponge 优化了虚拟机对 LargeObjectSpace 的内存管理策略,间接增加其它内存空间使用上限 (未开源)
- pthread hook 对 native 线程的默认栈大小进行减半
d.监控
接入KOOM,进行线下OOM发生时的采样上报
III.native crash
- google官网提供的native crash问题诊断思路
- 对Native Crash进行捕获,自定义实现自己的重启逻辑,比如重启/自定义上报crash等等
- 加载so失败,尝试用java替代的降级策略
6、防裂化&基础建设
a.版本回顾
崩溃数据自动化采集,以月度或者季度为纬度爬取数据,形成总结
b.崩溃保护和安全模式机制
- 通过ASM在编译时对四大组件生命周期等关键代码加上try-catch处理
- 通过一定的策略,针对反复重启导致的崩溃问题,让用户选择继续初始化或者清除数据
c.日志回捞
d.移动端性能中台
自建集崩溃监控、上报、分析、归因于一体(可以参考Matrix直接建立),可以轻松定位各种线上疑难杂症,更有超详细性能、卡顿、打点等全流程监控处理平台
链接:https://juejin.cn/post/7240037613793361976
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。