一.内存优化介绍及工具选择
1.内存问题
1).内存抖动:锯齿状,GC导致卡顿
2).内存泄漏:可用内存减少,频繁GC
3).内存溢出:OOM,程序异常
2.工具选择
1).Memory Profiler
a.实时图表展示应用内存使用量
b.识别内存泄漏,抖动等
c.提供捕获堆转储,强制GC以及跟踪内存分配的能力
特点:方便直观
2).MAT
a.强大的Java Heap分析工具,查找内存泄漏及内存占用
b.生成整体报告,分析问题等
c.线下深入使用
3).LeakCanary
a.自动内存泄漏检测
b.线下集成(线上容易导致OOM)
二.Android内存管理机制
1.java内存分配
方法区 虚拟机栈 本地方法栈 堆 程序计数器
2.java内存回收算法
1).标记-清除算法:
标记阶段:标记出可以回收的对象
清除阶段:回收被标记的对象所占用的空间
Android内存管理机制
1.内存弹性分配,分配值与最大值受具体设备影响
2.OOM场景:内存真正不足,可用内存不足
Dalvik与ART区别:
1.Dalvik仅固定一种回收算法
2.ART回收算法可运行期选择
3.ART具备内存整理能力,减少内存空洞
Low Memory Killer
1.进程分类
a.前台进程
b.可见进程
c.服务进程
d.后台进程
f.空进程等
2.回收收益
三.内存抖动实战
定义:内存频繁分配和回收导致内存不稳定
表现:频繁GC,内存曲线呈锯齿状
危害:导致卡顿,OOM
内存抖动导致OOM
1.频繁创建对象,导致内存不足及碎片(不连续)
2.不连续的内存片无法被分配,导致OOM
实战:
1.使用Memory Profiler初步排查
2.使用Memory Profiler或CPU Profiler结合代码排查
四.内存泄漏实战
定义:内存中存在已经没有用的对象
表现
危害:内存不足,GC频繁,OOM
解决:
使用Memory Profiler初步观察
通过MAT结合代码确认
五.ARTHook优雅检测不合理图片
1.Bitmap内存模型
1).API10之前Bitmap自身存在Dalvik Heap中,像素在Native中(不会自动回收)
2).API10之后Bitmap自身及像素存在Dalvik Heap中
3).API26之后像素在Native中(通知native层回收像素)
2.获取Bitmap占用内存
1).getByteCount
2).宽*高*一像素占用内存(注意:若放置在res中时,需要*压缩比例)
3.常规方式
背景:图片对内存优化至关重要,图片宽高大于控件宽高
实现:继承ImageView,复写实现计算大小
特点:侵入性强 不通用
4.ARTHook
相当于挂钩,将额外的代码勾住原有方法,修改执行逻辑
运行时插插桩
性能分析
Epic:是一个虚拟机层面,以Java Method为粒度的运行时Hook框架
支持Android4.0-9.0
特点:
无侵入性
通用性强
兼容问题大,开源方案不能带到线上环境
六.线程内存监控方案
1.常规实现一
设定场景线上Dump:Debug.dumpHprofData()
常规实现流程:
超过最大内存80%->内存Dump->回传文件->MAT手动分析
特点:
1).Dump文件太大,和对象数正相关,可裁剪
2).上传失败率高,分析困难
3).配合一定策略,有一定的效果
2.常规实现二
1).将LeakCanary带到线上
2).预设泄漏怀疑点
3).发现泄漏回传
特点:
不适合所有场景,必须设置怀疑点
分析比较耗时,也容易发生OOM
七.LeakCanary原理:
1.监控生命周期,onDestroy添加RefWatcher检测
2.二次确认断定内存泄漏
3.分析泄漏,找引用链
4.监控组件+分析组件
LeakCanary定制:
预设怀疑点-->自动找怀疑点
分析泄漏链路慢-->分析Retain size大的对象
分析OOM-->对象裁剪,不全部加载到内存
八.线上监控完整方案
待机内存,重点模块内存,OOM率
整体及重点模块GC次数,GC时间
增强的LeakCanary自动化内存泄漏分析
九.优化大方向
1.内存泄漏
2.内存抖动
3.Bitmap
十.内存优化模拟面试
1.内存优化项目的过程是怎么做的?
a.分析现状,确认问题
b.针对性优化
c.效率提升
2.做内存优化最大的感受是什么?
a.学习工具的使用
b.技术优化必须结合业务代码
c.系统化完善解决方案
3.如何检测所有不合理的地方?
ARTHook
重点强调区别