这个系列文章是对《深入理解Java虚拟机》一书的笔记及个人理解
标记清除算法
最基础的收集算法,后续算法都是基于这个算法进行改进。
如它的名字一样,算法分为”标记”和”清除”两个阶段:
首先标记出所有需要回收的对象,在标记完成后统一处理掉所有被标记的对象。
缺点:
1、效率低,标记和清除效率都不高
2、空间问题,清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致,当程序需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
运行过程如下图所示
复制算法
对标记-清除算法进行了改进,主要解决效率问题。
将可用内存按容量划分为大小相等的两块,每次只用其中一块,当这一块内存用完了,就将存活的对象复制到另外一块上面,然后把这一块的内存空间一次清理掉。
优点:实现简单,运行高效
缺点:内存小了一半,未免有点代价过高
如果每次回收时,存活的对象很多,则复制起来就不会显得高效了。所以这个算法只适用于,每次回收时,存活的对象占比很少的内存区域。
事实上商业虚拟机都采用这种算法来回收新生代。实际使用过程中也对其进行了进一步改进。
运行过程如下图所示:
标记-整理算法
复制算法并不适用于对象存活率高的内存区域,这时就需要标记-整理算法来解决。
运行过程跟标记-清除算法一样也是两个阶段,一阶段标记是一样的,但是二阶段并不是直接清除,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
分代收集算法
这个算法并没有什么新的思想,只是根据对象的存活周期的不同将内存划分为几块(一般是将Java堆划分为新生代和老年代),根据不同年代的特点采用适合的收集算法。
新生代使用复制算法
老年代使用标记-清理算法或标记-整理算法