成为一名优秀的Android开发,须要一份完备的知识体系,在这里,让咱们一块儿成长为本身所想的那样~。php
本篇是 Android 内存优化的进阶篇,难度能够说达到了炼狱级别,建议对内存优化不是很是熟悉的仔细看看前篇文章:Android性能优化以内存优化,其中详细分析了如下几大模块:java
1)、Android的内存管理机制算法
2)、优化内存的意义json
3)、避免内存泄漏数组
4)、优化内存空间缓存
5)、图片管理模块的设计与实现性能优化
若是你对以上基础内容都比较了解了,那么咱们便开始 Android 内存优化的探索之旅吧。工具
直接进入正题,冲冲冲!!!post
Android给每一个应用进程分配的内存都是很是有限的,那么,为何不能把图片下载下来都放到磁盘中呢?那是由于放在内存中,展现会更 “快”,快的缘由有两点,以下所示:性能
1)、硬件快:内存自己读取、存入速度快。
2)、复用快:解码成果有效保存,复用时,直接使用解码后对象,而不是再作一次图像解码。
这里说一下解码的概念。Android系统要在屏幕上展现图片的时候只认 “像素缓冲”,而这也是大多数操做系统的特征。而咱们常见的jpg,png等图片格式,都是把 “像素缓冲” 使用不一样的手段压缩后的结果,因此这些格式的图片,要在设备上展现,就必须通过一次解码,它的执行速度会受图片压缩比、尺寸等因素影响。(官方建议:把从内存中淘汰的图片,下降压缩比后存储到本地,以备后用,这样能够最大限度地下降之后复用时的解码开销。)
下面,咱们来了解一下内存优化的一些重要概念。
手机不使用PC的DDR内存,采用的是LPDDR RAM,即 ”低功耗双倍数据速率内存“。其计算规则以下所示:
LPDDR系列的带宽 = 时钟频率 ✖️内存总线位数 / 8LPDDR4 = 1600MHZ ✖️64 / 8 ✖️双倍速率 = 25.6GB/s。复制代码
那么内存占用是否越少越好?
当系统内存充足的时候,咱们能够多用一些得到更好的性能。当系统内存不足的时候,咱们但愿能够作到 ”用时分配,及时释放“。
对于Android内存优化来讲又能够细分为以下两个维度,以下所示:
1)、RAM优化
2)、ROM优化
一、RAM优化
主要是下降运行时内存。它的目的有以下三个:
1)、防止应用发生OOM。
2)、下降应用因为内存过大被LMK机制杀死的几率。
3)、避免不合理使用内存致使GC次数增多,从而致使应用发生卡顿。
二、ROM优化
下降应用占ROM的体积,进行APK瘦身。它的目的主要是为了下降应用占用空间,避免因ROM空间不足致使程序没法安装。
那么,内存问题主要是有哪几类呢?内存问题一般来讲,能够细分为以下三类:
1)、内存抖动
2)、内存泄漏
3)、内存溢出
下面,咱们来了解下它们。
一、内存抖动
内存波动图形呈锯齿张、GC致使卡顿。
这个问题在Dalvik虚拟机上会更加明显,而ART虚拟机在内存管理跟回收策略上都作了大量优化,内存分配和GC效率相比提高了5~10倍,因此出现内存抖动的几率会小不少。
二、内存泄漏
Android系统虚拟机的垃圾回收是经过虚拟机GC机制来实现的。GC会选择一些还存活的对象做为内存遍历的根节点GC Roots,经过对GC Roots的可达性来判断是否须要回收。内存泄漏就是在当前应用周期内再也不使用的对象被GC Roots引用,致使不能回收,使实际可以使用内存变小。简言之,就是对象被持有致使没法释放或不能按照对象正常的生命周期进行释放。通常来讲,可用内存减小、频繁GC,容易致使内存泄漏。
三、内存溢出
即OOM,OOM时会致使程序异常。Android设备出厂之后,java虚拟机对单个应用的最大内存分配就肯定下来了,超出这个值就会OOM。单个应用可用的最大内存对应于 /system/build.prop 文件中的 dalvik.vm.heapgrowthlimit。
此外,除了因内存泄漏累积到必定程度致使OOM的状况之外,也有一次性申请不少内存,好比说一次建立大的数组或者是载入大的文件如图片的时候会致使OOM。并且,实际状况下不少OOM就是因图片处理不当而产生的。
做用
1)、实时图表展现应用内存使用量。
2)、用于识别内存泄漏、抖动等。
3)、提供捕获堆转储、强制GC以及根据内存分配的能力。
优势
1)、方便直观
2)、线下使用
强大的Java Heap分析工具,查找内存泄漏及内存占用,生成总体报告、分析内存问题等等。建议线下深刻使用。
自动化内存泄漏检测神器。建议仅用于线下集成。
它的缺点比较明显,具体有以下两点:
1)、虽然使用了idleHandler与多进程,可是dumphprof 的 SuspendAll Thread 的特性依然会致使应用卡顿。
2)、在三星等手机,系统会缓存最后一个Activity,此时应该采用更严格的检测模式。
ART 和 Dalvik 虚拟机使用分页和内存映射来管理内存。下面咱们先从Java的内存分配开始提及。
Java的内存分配区域分为以下五部分:
1)、方法区:主要存放静态常量。
2)、虚拟机栈:Java变量引用。
3)、本地方法栈:native变量引用。
4)、堆:对象。
5)、程序计数器:计算当前线程的当前方法执行到多少行。
一、标记-清除算法
流程可简述为两步:
1)、标记全部须要回收的对象。
2)、统一回收全部被标记的对象。
优势
实现比较简单。
缺点
1)、标记、清除效率不高。
2)、产生大量内存碎片。
二、复制算法
流程可简述为三步:
1)、将内存划分为大小相等的两块。
2)、一块内存用完以后复制存活对象到另外一块。
3)、清理另外一块内存。
优势
实现简单,运行高效,每次仅需遍历标记一半的内存区域。
缺点
会浪费一半的空间,代价大。
三、标记-整理算法
流程可简述为三步:
1)、标记过程与 标记-清除算法 同样。
2)、存活对象往一端进行移动。
3)、清理其他内存。
优势
1)、避免 标记-清除 致使的内存碎片。
2)、避免复制算法的空间浪费。
四、分代收集算法
如今主流的虚拟机通常用的比较多的仍是分代收集算法,它具备以下特色:
1)、结合多种算法优点。
2)、新生代对象存活率低,使用 复制算法。
3)、老年代对象存活率高,使用 标记-整理算法。
Android 中的内存是弹性分配的,分配值 与 最大值 受具体设备影响。
对于OOM场景其实能够细分为以下两种:
1)、内存真正不足。
2)、可用(被分配的)内存不足。
咱们须要着重注意一下这两种的区分。
以Android中虚拟机的角度来讲,咱们要清楚Dalvik 与 ART 区别,Dalvik仅固定一种回收算法,而ART回收算法可在运行期按需选择,而且,ART具有内存整理能力,减小内存空洞。
最后,LMK(Low Memory killer)机制保证了进程资源的合理利用,它的实现原理主要是根据进程分类和回收收益来综合决定的一套算法集。
原文连接https://juejin.im/post/5e780257f265da575209652c
做者:jsonchao
后续小编将持续更新,帮助到你的话记得关注转发哦~~