学习JVM的垃圾回收,离不开的是追踪式垃圾回收算法,现有的主流Java虚拟机都采用的是追踪式回收算法。对比于引用计数式垃圾收集,追踪式垃圾回收算法都是采用的间接式的回收策略,也就是这种策略并非直接寻找垃圾本身,而是先寻找哪些对象存活,然后反过来判断其余所有的对象为垃圾对象。追踪式回收算法本身包括标记-清除(Mark-Sweep)、标记-复制(Mark-Copy)、标记-整理(Mark-Compact)这三种回收策略,在真正的回收器上,一定是根据对象的不同情况进行分区或者分代,针对不同的区域采取不同的回收策略,针对这些情况,有许多的相关基础概念展现出来。
追踪回收算法回收策略
追踪式回收算法本身包括标记-清除(Mark-Sweep)、标记-复制(Mark-Copy)、标记-整理(Mark-Compact)这三种回收策略,这三种策略都有一个共通之处。
标记-清除(Mark-Sweep)算法
标记-清除(Mark-Sweep)算法是一种典型的非移动式回收算法,是所有追踪式回收算法的基础,其他的算法都是针对标记-清除(Mark-Sweep)算法的缺点改进而来。
原理
在标记过程完成之后,将未标记的对象进行回收。
优缺点
优点:
1. 标记-清除(Mark-Sweep)算法的吞吐量(吞吐量就是处理器用于运行用户代码的时间与处理器总消耗时间的比值,吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 运行垃圾收集时间))较高;
2. 标记-清除(Mark-Sweep)算法对空间的利用率比较高,既不需要像标记-复制(Mark-Copy)算法划出多余的空间来进行复制对象,也不需要像引用计数算法为每个对象设置引用计数器;
缺点:
1. 标记-清除(Mark-Sweep)算法的执行效率不太稳定;
2. 标记-清除(Mark-Sweep)算法在清除的过程中会产生大量的碎片化空间,空间的碎片化太多,会导致程序在运行时分配对象的时候,无法找到足够大的连续空间,导致提前进行另一次垃圾收集;
标记-复制(Mark-Copy)算法
标记-复制(Mark-Copy)算法简称为复制算法,为了解决标记-清除(Mark-Sweep)算法面对大量可回收对象时,执行效率低的问题。
半区复制原理
基本的复制回收器会将堆划分称为两个大小相等的半区,分别是来源空间和目标空间。每次在程序运行时,只用其中的来源空间来进行对象的内存分配,当来源空间的内存不足时,进行垃圾回收,交换两个半区的角色,然后将存活的对象移到另一个半区的一端,最后将垃圾回收的半区内存清零。
半区复制优缺点
优点&#x