这是我参与「第四届青训营 」笔记创作活动的第 7 天。
今天开始实践二的开发学习,便复习了周三时《初识性能优化》这门课的笔记,也系统整理了一遍发出来大家一起学习。下面开始正式内容
一、本堂课重点内容
- 为什么要做性能优化
- 性能优化是什么
- 有哪些性能工具选型
- 如何做性能优化
二、详细知识点介绍
-
为什么要做性能优化
- 更好的体验和回报:性能优化能带来体验的改善、业务指标的提升
- 硬件性能优化速度变慢:软件的提升可以独立于硬件,而近几年的硬件优化性能变慢,软件提升才能获得更好的提升
- 为了适应未来更大的需求:寻求技术的进步
-
性能优化是什么
-
性能优化的目标:更快、更稳、更省
- 快:响应速度更快、交互快
- 稳:避免闪退等问题
- 省:储存、缓存空间、功耗更小
-
性能优化的分类:
-
流畅性优化:机制的响应与流畅的体验
-
资源优化:最小负载带来最大的收益
-
稳定性优化:稳定的实现、减少不必要的打断
-
系统级优化:扩展—底层booster
- 让APP在有限的资源里获得更多的资源、更快的运行
-
-
流畅性优化:
-
Android的线程结构:
-
界面是怎么刷新的:硬件发出vsync信号,保证没16毫秒刷新一次
-
卡顿是怎么产生的(三种原因):
-
解决卡顿:
- 耗时操作转移到其他线程
- 主线程只负责交互和刷新。
-
-
资源优化
-
资源是什么:
- Android的软件和硬件资源。
- 一般指应用依赖的移动端的有限资源和系统设置的数值
- 即功耗、存储、流量、系统参数、CPU和内存等
-
Android能做那些资源类的优化
-
-
稳定性优化
-
稳定性存在的问题:
-
ANR是什么
- Application Not Responding的缩写,程序无响应
- 如果Android应用的界面线程处于阻塞状态的时间过长,会触发App ANR错误。如果应用位于前台,系统会向用户显示对话框提供退出应用或等待的选项。
- 避免出现长时间卡顿,而采取的强制性退出方案
-
-
系统级优化:
-
-
最佳性能工具选型
-
要求:
- 消耗小:性能监控要求消耗很小
-
GPU呈现模式(初步发现问题):
-
原理:系统通过记录每一帧的相关数据,然后通过图形的形式呈现
-
优点:无需二次开发,简单易用
-
缺点:并不完全准确,且无法明确指出造成卡顿的具体原因
-
-
Layertool(字节自主开发)
- 原理:通过遍历ViewTree信息,输出View的层级关系
- 优点:清除明了,可以宏观感知ViewTree现状,也可以定制,帮助分析oveerdraw
- 缺点:还不能明确分析出UI的性能瓶颈
-
CPU Profiler(AS自带)
- 原理:基于JVMTI
- 优点:完整的方法调用栈输出、支持Java、C、C++方法检测耗时、上手简单
- 缺点:性能损耗大
-
TraceView
-
Instrument
- 虚拟监听入口回调 Enter / Exit / Unwind
- 耗时点:读时间、写数据到buffer,加锁等指令
-
Sample(采样模式)
- 通过顶是抓取多次堆栈diff,近似确定函数进入和退出时间
- 耗时点:堆栈diff、同Instrument
- 间隔抓取堆栈的时间越长性能损耗越少,而越会导致短函数检测不到
-
-
Systrace(goolge提供)
- ftrace:debugfs菜鸡和读取trace数据,记录trace events
- atrace:用户侧的trace跟踪,聚合所有的trace event
- 系统级Trace数据:锁监控 等
-
btrace(aka rhea)-进阶
- rhea-systrace:全函数插桩,自动生成Trace代码,对层数做限制,性能损耗50%
- rhea-mtrace:全函数插桩,抛弃systrace,自己统计函数耗时,最后数据展现同systrace
- rhea-atrace:优化systrace,集合更多性能数据:类加载、lock、IO等。
-
Battery Hisorian
- 监听一段时间的功耗因子(图为使用流程)
-
-
如何做性能优化
-
现状分析
-
耗时起因
- CPU Time:循环,反射,序列化 / 反序列化,类解析
- IO Wait:IO操作,等待IO结果
- IPC(为并发做提升):Binder调用耗时
- Lock Wait:主线程是等锁状态,等待其他线程或者自己超时唤醒
- CPU Schedule:主线程是可执行状态,但是获取不到CPU时间片
-
运行环境归因
- 主线程耗时
- 运行时耗时
- 后台进程耗时
-
渲染分析
-
过程
-
-
抖音耗时分析
-
-
性能策略
-
案例分析
-
分步优化
-
UI构建:xml IO、class反射、创建view、Asset资源大锁
- 抖音解决方案:AsyncLayoutInflater
-
渲染:
- 移除不必要的背景
- 修改不合理的布局
- 移除默认的Window背景
- 绘制层级优化:减少层级
-
-
-
三、课堂问答例子
-
人眼识别的不卡顿最小帧数:25帧
-
没有vsync信号会导致:画面撕裂
-
由于前一个没有绘制完,就来了新任务,导致部分绘制
-
一个布局从一个xml到View对象的耗时间
IO操作、类反射、View初始化、AssertManager资源
-