介绍及工具选择

内存问题

内存抖动:锯齿状,GC导致卡顿
内存泄漏:可用内存减少,频繁GC
内存溢出:OOM,程序异常

工具选择

Memory Profiler

实时图表展示应用内存使用量
识别内存泄漏,抖动等
提供捕获堆转储,强制GC以及跟踪内存分配的能力

Memory Analyzer

强大的Java Heap分析工具,查找内存泄漏及内存占用
生成整体报告,分析问题等
线下深度使用

LeakCanary

自动内存泄漏检测

内存管理机制

java内存回收算法

标记-清除算法

标记出所有需要回收的对象
统一回收所有被标记的对象
总结
标记和清除效率不高
产生大量不连续的内存碎片

复制算法

将内存划分为大小相等的两块
一块内存用完之后复制存活对象到另一块
清理另一块内存
总结
实现简单,运行高效
浪费一半空间,代价大

标记-整理算法

标记过程与“标记-清除”算法一样
存活对象往一端进行移动
清理其余内存
总结
避免标记-清理导致的内存碎片
避免复制算法的空间浪费

分代收集算法

结合多种收集算法优势
新生代对象存活率低,复制
老年代对象存活率高,标记-整理

Android内存管理机制

内存弹性分配,分配值与最大值受具体设备影响
OOM场景:内存真正不足,可用内存不足

Dalvik与Art区别

Dalvik仅固定一种回收算法
Art回收算法可运行期选择
Art具备内存整理能力,减少内存空洞

Low Memory Killer

进程分类
回收收益

内存抖动解决

内存抖动介绍

定义:内存频繁分配和回收导致内存不稳定
表现:频繁GC,内存曲线呈锯齿状
危害:导致卡顿,OOM

内存抖动导致OOM

频繁创建对象,导致内存不足及碎片(不连续)
不连续的内存片无法被分配,导致OOM

内存抖动解决实战

使用Memory Profiler初步排查,获取锯齿状时间段的内存分配对象,分析大数量和大内存的对象,通过对象找到代码位置,进行分析
使用Memory Profiler或CPU Profiler结合代码排查

内存抖动解决技巧

找循环或者频繁调用的地方

内存泄漏

定义:GC无法回收内存中没有用的对象
表现:内存抖动,可用内存逐渐减少
危害:内存不足,GC频繁,OOM

内存泄漏解决实战
使用Memory Profiler初步观察
通过Memory Analyzer结合代码确认

全面理解MAT

ARTHook优雅检测不合理图片

Bitmap内存模型

API10之前Bitmap自身在Dalvik Heap中,像素在Native中
API10之后像素也被放在Dalvik Heap中
API26之后像素在Native,当java对象回收后,很方便的通知到Natvie后进行回收像素

Bitmap占用内存

getByteCount
一像素占用内存*安卓资源文件夹图片加载到内存缩放比

常规方式

背景:图片对内存优化至关重要,图片宽高大于控件宽高
实现:继承Imageview,覆写实现计算大小
缺点:侵入型强,不通用

ARTHook介绍

挂钩,将额外的代码钩住原有方法,修改执行逻辑
运行时插桩
性能分析

Epic简介

github
Epic是一个虚拟机层面,以java Method 为粒度的运行时Hook框架
支持android 4.0到9.0

使用

compile ‘me.weishu:epic:0.3.6’
继承XC_MethodHook,实现相应逻辑
注入Hook:DexposedBridge.findAndHookMethod

优化技巧

优化大方向

内存泄漏
内存抖动
Bitmap

优化细节

LargeHeap属性
OnTrimMemory 系统低内存会掉
使用优化过的数据结构
谨慎使用SharedPreference
谨慎使用外部库
业务架构设计合理

模拟面试

内存优化项目过程是怎么做的

分析问题,确认问题:线上OOM,profiler 上发现内存抖动
针对性优化:解决抖动,
效率提升:不增加业务同学的开发量,使用了一些hook手段,内存优化文档建设,提高团队效率

你做内存优化最大的感受是什么

磨刀不误砍柴工(学习google官方文档,比如Memory profiler使用,Mat使用)
技术优化必须结合业务代码
系统化完善解决方案

如何检测所有不合理的地方

ARTHook
重点强调于其他方案区别