android软引用和弱引用 android强引用和弱引用



文章插图
android软引用和弱引用 android强引用和弱引用

文章插图
1、Android内存管理机制1.1 Java内存分配模型
先上一张JVM将内存划分区域的图
程序计数器:存储当前线程执行目标方法执行到第几行 。
栈内存:Java栈中存放的是一个个栈帧,每个栈帧对应一个被调用的方法 。栈帧包括局部标量表,
操作数栈 。
本地方法栈:本地方法栈主要是为执行本地方法服务的 。而Java栈是为执行Java方法服务的 。
方法区:该区域被线程共享 。主要存储每个类的信息(类名,方法信息,字段信息等)、静态变量,常量,以及编译器编译后的代码等 。
堆:Java中的堆是被线程共享的,且JVM中只有一个堆内存,主要存储对象本身及数组
1.2 Dalvik和ART介绍
Dalvik:Dalvik是Google公司自己设计用于Android平台的Java虚拟机 。它可以支持已转换为.dex格式的Java应用程序的运行,.dex格式是专门为Dalvik应用设计的一种压缩格式,适合内存和处理器速度有限的系统,Dalvik经过优化,允许在有限的内存中同时运行多个虚拟机实例,并且每一个Dalvik应用做为独立的Linux进程执行,独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭 。
ART:ART表示Android Runtime,Dalvik是依靠一个just-In -Time编译器去解释字节码,运行时编译后的应用都需要通过一个解释器在用户的设备上运行,这一机制并不是特别高效,但是能让应用更容易在不同的硬件和架构上运行 。ART则是完全改变了这种做法,在安装应用的时候就预编译字节码到机器语言,这一机制叫预编译 。在移除解释代码这一过程,应用程序执行将更有效率,启动速度更快 。
ART优点:
1.系统性能更高
2.应用启动速度,运行更快,体验更好,触感反馈更加及时 。
3.更长的电池续航能力
4.支持更低的硬件
ART缺点:
1.储存空间占用更大 。
2.应用安装时间更长 。
Dalvik与ART区别
1.Dalvik每次都要编译在运行,art只会安装时启动编译
2.art占用的空间比Dalvik要大,就是用空间换时间
3.art减少编译,减少CPU使用频率,使用明显改善电池续航
4.art启动,运行更快,体验更好,触感反馈更及时 。
1.3 为什么要进行内存优化
1.减少oom,提高应用的稳定性
2.减少卡顿,体验更好
3.减少内存占用,应用存活率更高
4.提前处理掉一些异常的隐患
2、Java内存回收算法2.1判断Java中对象是否存活的算法2.1.1 引用计数算法
堆内存的每个对象都有一个引用计数器,当对象被引用的时候,计数器+1,当引用失效时计数器-1,当计数器的值为0时,说明该对象没有被引用,就会被认为是垃圾对象,系统将会将其回收内存重新分配 。
优点:引用计数器执行简单,判定效率高 。
缺点:对于循环引用的对象难以判断出来,同时引用计数器增加了程序执行的开销,在jdk1.1后,就不在使用了 。
2.1.1 根搜索法
GC Roots的对象做为起点,然后向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则该对象不可达,也就是说该对象为为垃圾对象,可以被回收 。
在Java中,可以做为GC Roots的对象包括一下四种:
1.虚拟机栈中引用的对象
2.方法区中的类静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中JNI的引用对象
2.2 JVM垃圾回收算法2.2.1 标记清除法
最基础的垃圾收集算法,算法分为标记和清除两个阶段:首先标记出所有需要回收的对象,在标记完成之后统一回收掉所有被标记的对象 。
【android软引用和弱引用 android强引用和弱引用】缺点:效率低,其次会产生大量的不连续的内存碎片,导致提前触发另一次垃圾收集动作 。
2.2.2 复制回收算法
复制回收算法是将可用内存按容量分成大小相等的两块,每次只使用其中的一块,当这块内存使用完了,就将存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉,这样使得每都次都是对其中一块内存进行回收,内存分配时不用考虑内存碎片等复杂情况 。
缺点:可使用内存降为原来的一半 。
2.2.3 标记整理法
标记-整理算法在标记-清除算法的基础上做了改进,标记阶段将可回收的对象标记出来,标记完成后不是直接对可回收的对象进行清理,而是让所有存活的对象都向一端移动,在移动的过程中清理掉可回收的对象 。
优点:相比于标记清除法来说,标记整理法不会大量产生不连续内存碎片问题 。
缺点:如果是在对象存活率较高的情况下会执行较多的复制操作,效率将会降低很多,而在存活率较低的情况下,效率会大大提高 。
2.2.4 分代收集回收算法
当前商业虚拟机都是采用的是分代收集算法,根据对象存活的周期不同将内存划分为几块,一般是将java堆分为年轻代,老年代和永久代 。然后根据各个年代的特点来采取不同收集算法,年轻代存活率较低,采用复制回收算法,老年代对象存活率较高,采用标记清除法或者是标记整理法来进行回收 。
3、内存问题表现形式3.1 内存抖动
内存波动图呈锯齿状,gc频繁导致卡顿 。
3.2 内存泄漏
内存泄露简单来说就是系统分配出去的内存由于某种原因导致没法释放,内存会越来越小,最终导致oom 。
3.3 内存溢出
即OOM,OOM时会导致程序异常 。Android设备出厂以后,java虚拟机对单个应用的最大内存分配就确定下来了,超出这个值就会OOM 。
4、内存优化常用工具4.1 Memory Profiler
Memory Profiler是Android studio自带的工具,实时图表形式展示应用内存使用的情况,可以用来识别内存泄露,抖动等
注意:如果在控制台中没有找到Profiler,可View —–> Tool Windows —> Profiler 进行打开
优点:方便直观,便于线下使用
4.2 Memory Analyzer(MAT)
1、强大的java heap分析工具,查找内存泄露及内存占用
2、生成整体报告,便于分析问题
3、可以在线下深入使用
MAT使用:
MAT下载地址: