Java 垃圾回收算法

垃圾回收算法

垃圾回收(Garbage Collection,简称GC)是 Java 虚拟机(JVM)自动管理内存的一种机制,用于回收不再使用的对象所占用的内存空间,从而避免内存泄漏和手动管理内存的复杂性。对于如何判定一个对象是否应该被回收,请参见之前的文章: Java引用类型

以下是几种常见的垃圾回收算法:

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

基本原理
  • 标记阶段:从每个 GC Roots 开始,递归遍历所有可达的对象,并将这些对象标记为存活。
  • 清除阶段:遍历整个对象内存区域,清除未标记的对象(即垃圾对象)。

在这里插入图片描述

优点
  • 算法简单,容易实现
缺点
  • 效率问题:标记和清除过程效率不高,尤其是在对象数量较多的情况下。
  • 空间碎片:标记清除后,会产生大量不连续的内存碎片,影响后续对象的分配。

标记清除算法是最基础的垃圾回收算法,后续的算法都是基于这种思路并对其不足进行改进而得到的。

2. 复制算法(Copying)

复制算法解决了内存碎片问题,并且这个算法也是分代算法的基础。

基本原理

将内存分为两个相等的区域,每次只使用其中一个区域。当该区域满时,将存活的对象复制到另一个区域,然后清除原区域的所有对象。

在这里插入图片描述

优点
  • 执行效率高:只需要移动存活对象并更新指针,不需要进行复杂的标记和清除操作
  • 无内存碎片:复制过程中会将存活对象连续地存储在新的区域,避免了内存碎片化
缺点
  • 内存利用率低:每次只能使用一半的内存空间,内存空间浪费
  • 对象存活数量较多时,复制性能较差

适用于新生代区域,因为新生代对象的生命周期较短,死亡率高,复制存活对象的开销相对较小。

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

复制算法在对象存活率较高时,需要进行较多的复制操作,效率将会变低,更关键的是,如果不想浪费 50% 的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都 100% 存活的极端场景,所以在老年代一般不能直接使用复制算法。根据老年代的特点,有人提出了“标记-整理”算法。

基本原理
  • 标记阶段:与“标记-清除”算法相同,标记所有存活的对象。
  • 整理阶段:将所有存活的对象向内存的一端移动,然后更新指针,清除边界外的内存区域。

在这里插入图片描述

优点
  • 避免内存碎片化:通过移动对象,使得内存空间更加连续,提高了内存利用率。
缺点
  • 执行效率相对较低:需要移动对象并更新指针,操作较为复杂。

在老年代一般会用这种标记-整理算法。

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

基本原理

根据对象存活周期的不同将内存分为几块,一般是把 Java 堆分为新生代和老年代,根据各个年代的特点采用最适当的回收算法。

在新生代,每次 GC 时都发现有大量对象死去,只有少量存活,那就采用复制算法,只需付出少量存活对象的复制成本就可以完成收集。

在老年代,因对象存活率高,没有额外空间对它进行分配担保,就必须采用“标记-清除”或“标记-整理”算法来进行回收。

参考
《深入理解 Java 虚拟机》
必知必会JVM垃圾回收——对象搜索算法与回收算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值