JVM有哪些垃圾回收算法?

  1. MarkSweep 标记清除算法:这个算法分为两个阶段,1.标记阶段:把垃圾内存标记出来,2.清除阶段:直接将垃圾内存回收。这种算法是⽐较简单的,但是有个很严重的问题,就是会产⽣⼤量的内存碎⽚。

  2. Copying 拷⻉算法:为了解决标记清除算法的内存碎⽚问题,就产⽣了拷⻉算法拷⻉算法将内存分为⼤⼩相等的两半,每次只使⽤其中⼀半。垃圾回收时,将当前这⼀块的存活对象全部拷⻉到另⼀半,然后当前这⼀半内存就可以直接清除。这种算法没有内存碎⽚,但是他的问题就在于浪费空间。⽽且,他的效率跟存货对象的个数有关

  3. MarkCompack 标记压缩算法:为了解决拷⻉算法的缺陷,就提出了标记压缩算法。这种算法在标记阶段跟标记清除算法是⼀样的,但是在完成标记之后,不是直接清理垃圾内存,⽽是将存活对象 往⼀端移动,然后将端边界以外的所有内存直接清除。

这三种算法各有利弊,各⾃有各⾃的适合场景。

在 JVM 中,垃圾回收算法是垃圾回收器(Garbage Collector, GC)的核心组成部分,用于识别和回收不再使用的对象。JVM 提供了多种垃圾回收算法,每种算法适用于不同的场景和需求。下面我们详细介绍 JVM 中的主要垃圾回收算法及其特点。


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

(1)原理
  • 标记:从 GC Roots 出发,遍历所有可达对象,并标记它们为活动对象。

  • 清除:遍历堆内存,释放所有未被标记的对象占用的内存。

(2)优点
  • 实现简单,适用于大多数场景。

(3)缺点
  • 会产生内存碎片,影响内存分配效率。

  • 清除阶段需要遍历整个堆内存,性能较低。

(4)适用场景
  • 适用于老年代垃圾回收。


2. 标记-整理算法(Mark-Compact)

(1)原理
  • 标记:从 GC Roots 出发,遍历所有可达对象,并标记它们为活动对象。

  • 整理:将所有活动对象移动到内存的一端,减少内存碎片。

(2)优点
  • 避免了内存碎片,提高了内存分配效率。

(3)缺点
  • 整理阶段需要移动对象,增加了额外的开销。

(4)适用场景
  • 适用于老年代垃圾回收。


3. 复制算法(Copying)

(1)原理
  • 将堆内存分为两个区域:From 区和 To 区。

  • 复制:将 From 区中的活动对象复制到 To 区,并清空 From 区。

  • 交换:交换 From 区和 To 区的角色。

(2)优点
  • 避免了内存碎片,提高了内存分配效率。

  • 复制算法的效率较高,适合处理存活对象较少的情况。

(3)缺点
  • 需要额外的内存空间(From 区和 To 区)。

  • 适合存活对象较少的情况,如果存活对象较多,复制开销较大。

(4)适用场景
  • 适用于新生代垃圾回收。


4. 分代收集算法(Generational Collection)

(1)原理
  • 将堆内存分为新生代(Young Generation)和老年代(Old Generation)。

  • 新生代:使用复制算法(Copying)。

  • 老年代:使用标记-清除算法(Mark-Sweep)或标记-整理算法(Mark-Compact)。

(2)优点
  • 根据对象的生命周期采用不同的回收策略,提高了垃圾回收的效率。

(3)缺点
  • 实现复杂,需要维护多个内存区域。

(4)适用场景
  • 适用于大多数 JVM 垃圾回收器。


5. 增量收集算法(Incremental Collection)

(1)原理
  • 将垃圾回收过程分为多个小步骤,与应用线程交替执行。

  • 每次只回收一部分垃圾,减少单次回收的暂停时间。

(2)优点
  • 减少了单次回收的暂停时间,提高了应用的响应速度。

(3)缺点
  • 总体回收时间可能较长。

  • 实现复杂,需要额外的同步机制。

(4)适用场景
  • 适用于需要低延迟的应用。


6. 并发标记清除算法(Concurrent Mark-Sweep, CMS)

(1)原理
  • 初始标记:标记 GC Roots 直接引用的对象(需要暂停应用线程)。

  • 并发标记:并发标记所有可达对象。

  • 重新标记:修正并发标记期间发生变化的对象(需要暂停应用线程)。

  • 并发清除:并发清除所有未被标记的对象。

(2)优点
  • 减少了暂停时间,提高了应用的响应速度。

(3)缺点
  • 会产生内存碎片。

  • 需要额外的 CPU 资源。

(4)适用场景
  • 适用于需要低延迟的应用。


7. G1 算法(Garbage-First)

(1)原理
  • 将堆内存划分为多个区域(Region),每个区域可以是新生代或老年代。

  • 初始标记:标记 GC Roots 直接引用的对象(需要暂停应用线程)。

  • 并发标记:并发标记所有可达对象。

  • 最终标记:修正并发标记期间发生变化的对象(需要暂停应用线程)。

  • 筛选回收:优先回收垃圾最多的区域(Garbage-First)。

(2)优点
  • 平衡了吞吐量和延迟。

  • 避免了内存碎片。

(3)缺点
  • 实现复杂,需要维护多个区域。

(4)适用场景
  • 适用于大内存和多核 CPU 的应用。


8. 总结

算法原理优点缺点适用场景
标记-清除标记活动对象,清除未标记对象。实现简单。产生内存碎片,性能较低。老年代垃圾回收。
标记-整理标记活动对象,整理内存。避免内存碎片。整理阶段开销较大。老年代垃圾回收。
复制算法将活动对象复制到另一个区域。避免内存碎片,效率高。需要额外内存空间。新生代垃圾回收。
分代收集根据对象生命周期采用不同策略。提高回收效率。实现复杂。大多数 JVM 垃圾回收器。
增量收集将回收过程分为多个小步骤。减少单次回收的暂停时间。总体回收时间较长。需要低延迟的应用。
并发标记清除并发标记和清除。减少暂停时间。产生内存碎片,需要额外 CPU 资源。需要低延迟的应用。
G1 算法分区回收,优先回收垃圾最多的区域。平衡吞吐量和延迟,避免内存碎片。实现复杂。大内存和多核 CPU 的应用。

9. 一句话总结

JVM 提供了多种垃圾回收算法,包括标记-清除、标记-整理、复制算法、分代收集、增量收集、并发标记清除和 G1 算法,每种算法适用于不同的场景和需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EthanMilk

你的鼓励是我创作的最大动力谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值