内存问题
内存抖动:通过工具可以发现是锯齿状 , 可导致GC频繁,GC频繁会导致程序卡顿。
内存泄漏:可用内存减少,导致内存多次回收,频繁GC会导致程序卡顿。
内存溢出:OOM, 程序异常。
工具
MemoryProfiler
实时图表反应内存的使用情况
识别内存泄漏,抖动
Memory Analyzer (MAT)
LeakCanary
Android 内存管理机制
Java内存管理机制
Android内存管理机制
Java内存分配
将一大块内存划分为好几个部分
方法区 (类,静态变量...) :所有线程共享
虚拟机栈(局部变量..) 为Java方法服务,都是一些引用
本地方法栈:为native方法服务。
堆(内存中最大的区域):所有线程共享,我们对象的分配实际上都是堆上内存的分配。 经常说的内存泄漏就是发生在堆内存当中的。
程序计数器:.... 有这么个东西,来记录执行当前方法执行到了第几行。
虚拟机栈中应用 都是指向堆中真正创建的对象
Java内存回收算法
- 标记-清除算法
标记出所有需要被回收的对象
统一将回收所有被标记的对象。
缺点:效率不高 , 会出现大量内存碎片,这些碎片不可被用。 - 复制算法
实现简单,运行高效浪费一半内存 - 标记-整理算法
避免了标记清楚算法出现的内存空洞
避免了浪费一半内存 - 分代收集算法
结合多种手机算法的优势
新生代存活率低采用复制算法
老年代存活率高,采用标记
Android内存管理机制
内存弹性分配,分配值和最大值受设备影响
OOM场景: 内存真正不足(app本身已经达到分配的内存值),可用内存不足(即使系统回收其他的进程也不足以) 就会保出 OutOfMemory
Dalvik 和Art区别
Dalvik仅一种回收算法,出厂就已经确定了
Art是可以在运行期选择。可以在不同的情况下选择不同的垃圾回收算法。
Low Memory Killer
针对所有进程
内存抖动
内存频繁回收导致内存不稳定,使用工具查看就是锯齿状
会导致卡顿,严重会导致OOM
-频繁创建对象,导致内存不足或碎片 (不连续)
-不连续的内存片无法被分配,导致OOM
解决方案:
使用Memory Profiler初步排查 Profiler -> Record 基本可以找到出现问题的位置。多半出现在循环或者多次调用的地方。
内存泄漏:
内存中存在没有使用过的对象
表现:出现内存抖动,可用内存变少。
危害: 内存不足,GC频繁,OOM
解决方案:
使用Memory Profiler 初步检查
使用MAT 结合代码确定位置
MAT工具使用 (32:00)
ARTHook检测不合理图片
Bitmap内存模型
获取Bitmap占用内存
getByteCount(); 返回Bitmap自身所占的内存
因为图片对于内存优化至关重要,图片宽高大于控件宽高
解决这个问题的方案可以有 继承ImageView,重写onDraw()方法计算控件大小,再计算填入控件的Bitmap的大小,如果超出一定比例就要做一些事情,压缩或者... . 但是 不好用吧。
... ARTHook - epic 库 ...
(线上内存监控方案)
.... 算了吧
内存优化技巧总结
优化大方向
内存泄漏
内存抖动
Bitmap
内存优化的细节:
使用优化过的SparseArray
谨慎使用SharedPreference
谨慎使用外部库
合理设计架构
Q: 项目内存优化的过程是怎样做的
分析现状,确认问题
针对性解决
效率提升 (无侵入性,使用些工具类)
Q:如何检测不合理的地方
ARTHook
以及与其他方案的区别