一.卡顿介绍及优化工具选择
背景介绍:
1.很多性能问题不易被发现,但卡顿很容易被直观感受
2.卡顿问题难以定位排查
a.产生原因错综复杂:代码,内存,绘制,IO?
b.不易复现:当时场景强相关
工具介绍:
1.CUP Profiler:
a.图形的形式展示执行时间,调用栈等
b.信息全面,包含所有线程
c.运行时开销严重,整体都会变慢,可能会带偏优化方向
使用方式:
Debug.startMethodTracing("")
Debug.stopMethodTracing("")
生成文件在sd卡:Android/data/packegename/files 直接打开
2.Systrace:
a.监控和跟踪Api调用,线程运行情况,生成Html报告
b.API18以上使用,推荐TraceCompat
优点:轻量级,开销小
3.StrictMode
a.严苛模式,Android提供的一种运行时检测机制
b.方便强大,容易被忽视
c.包含:线程策略和虚拟机策略检测
线程策略:
1.自定义的耗时调用,detectCustomSlowCalls()
2.磁盘读取操作,detectDiskReads
3.网络操作,detectNetwork
虚拟机策略:
1.Activity泄漏,detectActivityLeaks()
2.Sqlite对象泄漏,detectLeakedSqlLiteObjects
3.检测实例数量,setClassInstanceLimit()
二.自动化卡顿检测方案及优化
为什么需要自动化检测方案?
1.系统工具适合线下针对性分析
2.线上及测试环节需要自动化检测方案
方案原理:
1.消息处理机制,一个线程只有一个Looper
2.mLogging对象在每个message处理前后被调用
3.主线程发生卡顿,是在dispatchMessage执行耗时操作
具体实现:
1.Looper.getMainLooper().setMessageLogging()
2.匹配>>>>>Dispatching,阈值时间后执行任务(获取堆栈)
3.匹配<<<<<Finished,任务启动之前取消掉
AndroidPerformanceMonitor:
1.非侵入式的性能监控组件,通知形式弹出卡顿信息
2.方便精准,定位到代码的某一行
缺点:
1.卡顿堆栈可能不准确
2.和OOM一样,最后的堆栈只是表象,不是真正的问题
优化:
获取监控周期内的多个堆栈,而不仅是最后一个
startMonitor-->高频采集堆栈-->endMonitor-->记录多个堆栈-->上报
高频卡顿上报量太大,服务端有压力,优化处理:
1.分析:一个卡顿下多个堆栈大概率有重复
2.解决:对一个卡顿下堆栈进行hash排重,找出重复的堆栈
3.效果:极大的减少展示量,同时更高效找到卡顿堆栈
三.ANR分析与是实战
1.ANR介绍:
a.KeyDispatchTimeout,5s
b.BroadcastTimeout,前台10s,后天60s
c.ServiceTimeout,前台20s,后台200s
d.ContentProviderTimeout,10s
2.ANR执行流程:
a.发生ANR
b.进程接收异常终止信号,开始写入进程ANR信息
c.弹出ANR提示框(Rom表现不一)
3.ANR解决套路(线下):
a.adb pull data/anr/traces.txt 存储路径
b.详细分析:CPU,IO,锁
4.线上ANR监控方案
a.通过FileOberver监控文件变化,注意高版本权限限制
b.ANR-WatchDog:非侵入式的ANR监控组件
实现原理:
start-->post消息改值-->sleep-->检测是否修改-->判断ANR发生
自身项目中:复写其listener,自己处理堆栈信息,上报服务器
5.AndroidPerformanceMonitor与ANR-WatchDog区别:
a.AndroidPerformanceMonitor:监控Msg
b.ANR-WatchDog:看最终结果
c.前者适合监控卡顿,后者适合补充ANR监控
四.卡顿单点问题检测方案
背景介绍:
1.自动卡顿检测方案并不够满足所有场景的要求
2.体系化解决方案务必尽早暴露问题
3.单点问题:主线程IPC,DB操作
IPC问题监测:
1.监测指标:
a.IPC调用类型
b.调用耗时,次数
c.调用堆栈,发生线程
常规方案:IPC前后加埋点
监测技巧:
adb命令:adb shell am trace-ipc start
adb shell am trace-ipc stop --dump-file /data/local/tmp/ipc-trace.txt
adb pull /data/local/tmp/ipc-trace.txt
优雅方案:
1.ARTHook还是AspectJ?
2.ARTHook:可以Hook系统方法
3.AspectJ:非系统方法
总结:
1.利用ARTHook完善线下工具
2.开发阶段Hook相关操作,暴露,分析问题
3.监控维度:IPC,IO,DB,View绘制
五.如何实现界面秒开?
1.可把界面秒开当做一个小的启动优化
2.可借鉴启动优化及布局优化章节
3.Systrace,优雅异步+优雅延迟初始化
4.异步Inflate,X2C,绘制优化
5.提前获取页面数据
Lancet:轻量级Android AOP框架:
1.编译速度快,支持增量编译
2.API简单,没有任何多余代码插入apk
@Proxy:通常用于对系统API调用的Hook
@Insert:常用于操作App与Library的类
监控维度:
1.总体耗时
2.生命周期耗时
3.生命周期间隔耗时
六.优雅监控耗时盲区
背景:
1.生命周期的间隔
2.onResume到Feed展示的间隔
监控难点:
1.只知道盲区时间,不清楚具体在做什么
2.线上盲区无从排查
线下方案:TraceView:特别适合一段时间内的盲区监控
线上方案思考分析:
1.主线程所有方法是Msg,mLogging?没有Msg具体堆栈
2.AOP切Handler方法?不清楚准确执行时间
最终实现:
1.使用统一的Handler:定制具体方法
2.定制gradle插件,编译期动态替换
七.卡顿优化技巧总结
1.实践经验
a.耗时操作:异步,延迟;
b.布局优化:异步Inflate,X2C,重绘解决;
c.内存:降低内存占用,减少GC时间;
2.工具建设:系统工具认识及使用
a.Systrace,TraceView,StrictMode
b.自动化监控及优化:AndroidPerformanceMonitor,ANR-WatchDog;高频采集,找出重复率高的堆栈;
3.卡顿监控工具:单点问题:AOP,Hook;盲区监控:gradle编译期替换
4.监控指标:a.卡顿率,ANR率,界面秒开率;b.交互时间,生命周期时间;c.上报环境,场景信息;
八.模拟面试
1.你是怎么做卡顿优化的?
第一阶段:系统工具定位,解决;
第二阶段:自动化卡顿方案及优化;
第三阶段:线上监控及线下监测工具建设;
2.怎么自动化的获取卡顿信息?
思路来自Android消息处理机制,mLogging.pringIn;高频采集,找出重复堆栈;
3.卡顿的一整套解决方案是怎么做的?
a.线上,线下工具相结合;
b.特定难题突破:单点问题,盲区监控;
c.线上监控建设