JVM垃圾收集的几种算法?

1.分代垃圾收集理论

上次在讲解 Java 运行时数据区域的划分时说过,Java 垃圾收集的主要区域就是 Java 堆。

一般至少会把 Java 堆划分为新生代和老年代两个区域。

新生代中,每次垃圾收集时都会有大批对象死去,而每次回收后存活的少量对象,将会逐步晋升到老年代中存放。新生代中一般存放的是存活时间比较短且比较小的对象。

老年代中一般放置的是大对象,或者是在新生代中经过多次垃圾回收依然存活的对象,这些存活时间较长的对象会进入到老年代区域中。

2.标记-清除算法

2.1 原理

标记-清除如它的名字一样,该算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象

2.2 示意图

在这里插入图片描述

2.3 缺点
  • 执行效率不稳定:如果 Java 堆中包含大量对象,而其中大部分是需要被回收的,这时必须进行大量标记和清除的动作,导致标记和清除两个过程的执行效率都随着对象数量增长而降低。
  • 内存空间碎片化问题:标记,清除后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时无法提供足够的连续内存而不得不提前触发另一次垃圾收集动作。

3.标记-复制算法

3.1 原理

为了弥补标记-清除算法面对大量可回收对象时执行效率低的问题,提出了“半区复制”的垃圾收集算法。

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

3.2 示意图

在这里插入图片描述

3.3 缺点

标记-复制算法虽然解决了标记-清除算法面对大量可回收对象时执行效率低的问题,但是它会在有大量对象存活的情况下,产生大量的内存复制开销。同时该算法将可用的内存缩小了一半,空间浪费问题比较严重。

3.4 优化

针对标记-复制算法的性能优化问题,官方提出了一种更优化的半区复制分代策略,将内存分为一块较大的 Eden 区和两个较小的 Survior 区,Eden:Survior = 8:1。每次只是用 Eden 和一块 Survior 区。

垃圾回收时,将存活的对象复制到另一块未使用的 Survivor 区域。如果当 Survior 空间不足时,就需要老年代进行担保。

4. 标记-整理算法

4.1 原理

标记-整理算法的标记过程与标记-清除算法中的标记过程相同,但是后续步骤不是直接对回收对象进行清理。而是让所有存活对象都向内存空间一段移动,然后直接清理掉边界以外的内存。

4.2 示意图

在这里插入图片描述

4.3 缺点

相比标记-清除算法而言,标记-整理算法保证了内存的连续性,但是在大对象的处理上性能不是很高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值