垃圾收集算法
首先介绍一下如何判断一个对象是否已死:
1、引用计数法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值加一;当引用失效时计数器减一。当计数器值为0时,代表对象已经不再被引用。
缺点:无法解决相互循环引用问题。
2、可达性分析算法(JVM用该算法):从一系列的“GC Roots”作为对象的起点开始向下搜索,走过的路径称为引用链,当一个对象到GC Roots没有任何引用链时,代表对象不再被引用。
GC Roots 包含如下:
A、虚拟机栈中引用的对象。
B、方法区中静态属性引用的对象。
C、方法区中常量引用的对象。
D、本地方法栈中JNI(本地方法)引用的对象。
一、标记——清除 (Mark-Sweep)
最基础的收集算法,如同它的名字一样,算法分为“标记”和“清除”两个阶段。
工作方式: 首先,标记出所有需要回收的对象。在标记完成后,再统一回收所有被标记的对象。
优点:最基础的垃圾收集算法,所有的垃圾收集算法,都是根据该算法衍生改进而成的。
缺点:
1、标记和清除这两个过程的效率不高。
2、清除之后,会产生大量不连续的内存碎片。(空间碎片过多,可能会导致在分配较大对象时,无法找到合适的内存而触发垃圾收集)
二、复制算法
工作方式:复制算法将可用的内存均分为大小相等的两块,每次只使用其中的一块,当一块的内存用完了,就将还存活的对象复制到另一块上面,然后把已使用过的内存块清理掉。
HotSpot 就是使用这样的收集算法来回收新生代的。它将新生代分为 Eden和两个Survivor,它们的比例为 8:1,因此每次只有10%的内存空闲。
缺点:
1、有内存浪费。
2、当对象存活率高时,需要较多的复制操作,效率会下降。
三、标记——整理(Mark-Compact)
根据老年代的特点(存活率高),人们提出了标记-整理算法。
工作方式:首先标记出所有需要回收的对象。在标记完成后,让所有存活的对象往一端移动,最后在清理存活对象之外的内存。