原创

虚拟机垃圾算法

在 Hotspot JVM 中,大致有以下四种垃圾收集算法:

1.标记-清除(Mark-Sweep)算法

它是最基础的算法,分为 2 个阶段“标记”和“清除”:首先标记出所有需要回收的对象,在标记完后统一回收掉所有被标的对象。 之所以说它是最基础的收集算法,是因为后续的搜集算法都是基于这种思路并改进其缺点而来的。

标记-清除算法主要有两个缺点:

  • 1、标记和清除的效率都不高;
  • 2、会产生许多内存速碎片,内存碎片会导致在运行时保分配较大的对象时,由于无法找到连续的内存而不得不提前触发一次垃圾收集操作。 标记清除算法示意图

2.复制(copying)算法

该算法将 JVM 可用的内存按容量划分为对等的两块,每次只使用其中的一块,当其中一块使用完后,就将还存活的对象拷贝到另外一块上,然后把已使用过的内存一次清空。

复制算法优点是实现简单,效率高,但是由于每次只使用一半的内存空间,这就会浪费掉一般的内存容量。

另外,复制算法在对象存活率较高的情况下要执行较多的复制操作,效率会变低。

3.标记-整理(mark-compact)算法

前期标记过程和“标记-清除(Mark-Sweep)”算法一样,但后续操作不是直接清除可回收对象,而是让所有存活的对象都向内存的一端移动,然后直接清理掉边界以外的内存。 其示意图如下:

标记整理算法示意图
标记整理算法示意图

4.分代收集算法

当前 JAVA 商业虚拟机的垃圾收集都是采用“分代收集”算法,该算法主要根据对象的存活周期的不同将内存划分为几块。 一般是把 JAVA 的堆分为新生代和老年代,这样就可以根据各个年代的特点采用最恰当的手机算法。新生代中的对象大都“朝生夕死”,只有少量的存活, 这样就可以选择复制算法;而老年代中对象因为存活率高、没有额外空间担保,就必须使用“标记-清除”或“标记-整理”算法来回收。

分代收集
分代收集

Young Generation:从 eden 区分配新对象,eden 区满后,发生一次 minor garbage collection,把 eden 区和一个 survivor 区中存活的对象移动到另一个 survivor 区中,存活的对象 age 加 1,当存活的对象 age 达到一个阈值时晋升到 Old Generation。

Old Generation:保存存活长久对象的地方,Old Generation 满后会发生 major garbage collection(full garbage collection)。

Stop the World Event:minor garbage collection 和 major garbage collection 都是 Stop the World Event,即垃圾回收的时候会暂停程序中线程的执行。

Permanent generation:保存 JVM 中用于描述类和方法的元数据信息。

正文到此结束