JVM的垃圾收集算法

2022-03-26  本文已影响0人  代码的搬运工

1、分代收集理论

收集器应该将Java堆划分出不同的区域,然后将回收对象依据其年龄(年龄即对象熬过垃圾收集过程的次数)分配到不同的区域之中存储。

在Java堆划分出不同的区域之后,垃圾收集器才可以每次只回收其中某一个或者某些部分的区域——因而才有了“新生代收集(Minor GC/Young GC)”、“老年代收集(Magor GC/Old GC)”和“整堆收集(Full GC)”这样的回收类型的划分;也才能够针对不同的区域安排与里面存储对象存亡特征相匹配的垃圾收集算法——因而发展出了“标记-清除算法”、“标记-复制算法”和“标记-整理算法”等针对型的垃圾收集算法。

2、标记-清除算法

标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。

它的主要缺点有两个:第一个时执行效率不稳定,第二个时内存空间碎片化严重。

标记-清除算法的执行过程如下图所示:

3、标记-复制算法

将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

它的主要缺点是内存空间浪费严重。

标记-复制算法的执行过程如下图所示:

现在的商用Java虚拟机大多都优先采用了这种收集算法去回收新生代。

将整个新生代按照8:1:1的比例划分为三块,最大的称为Eden区,较小的两块分别称为Survivor0区和Survivor1区。

对象先在Eden区中分配,首次GC时,将Eden区存活的对象复制到Survivor0区(此时Survivor1区为空),Eden区整体回收。对象接着在Eden区中分配,再次GC时,将Eden区和Survivor0区存活的复制到Survivor1区,Eden区和Survivor0区整体回收,接下来就是循环往复这个过程。直到年龄达到阈值(默认为15),进入老年代。

注:大对象直接进入老年代

4、标记-整理算法

标记出所有需要回收的对象或标记出所有存活的对象,在标记完成后,让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存。

它的缺点是操作复杂并且得全程暂停用户应用程序(Stop The World,STW)。

标记-整理算法的执行过程如下图所示:

上一篇 下一篇

猜你喜欢

热点阅读