常见的垃圾回收算法

本文介绍了四种常见的垃圾回收算法:引用计数、复制、标记清除和标记整理。引用计数适用于简单场景但处理循环引用困难;复制算法在年轻代使用,有效避免内存碎片但浪费一半空间;标记清除适合老年代,但效率较低且易产生碎片;标记整理则解决了清除阶段的碎片问题,使存活对象集中,但有移动对象的开销。

1、常见的垃圾回收算法

1.1 引用计数

在这里插入图片描述
原理:只要对象之间互相有引用,也就是,只要对象被引用了,GC 就不进行垃圾回收

缺点

  • 每次对对象赋值时要维护引用计数器,且计数器本身也有一定的消耗
  • 比较难处理循环引用

JVM 的实现一般不采用这种方式。

1.2 复制

年轻代中使用的是Minor GC,这种 GC 算法采用的是复制算法。

原理:将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。如下图:从根集合(GC Root)开始,通过 Tracing 从 From 中找到存活对象,拷贝到 To 中,然后 From 和 To 交换身份,下次内存分配从 To 开始。
在这里插入图片描述
优点

  • 没有标记和清除的过程,效率高
  • 内存在分配时不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可

缺点

  • 将实际可用的内存空间缩小为了原来的一半

1.3 标记清除

老年代一般是由标记清除或是标记清除与标记整理的混合实现。

原理:算法分为 标记 和 清除 两个阶段。首先标记出所有需要回收的对象(标记),在标记完成后统一回收所有被标记的对象(清除)。

优点

  • 所有的操作都是在一块内存空间上完成的,不需要额外的空间

缺点

  • 标记 和 清除 两个过程的效率都不高:标记需要扫描1次,清除也需要扫描1次,两次扫描,耗时严重
  • 标记清除后,会产生大量不连续的内存碎片,空间碎片太多可能会导致以后程序在运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾回收。

1.4 标记整理

标记整理一般发生在老年代区域。

原理:和标记清除算法一样,不同的是,在标记完后,不是直接清理可回收对象,而是让所有存活的对象都向一端移动,然后清理掉端边界以外的内存。

优点

  • 清理时,不会产生大量连续的内存碎片

缺点

  • 需要移动对象的成本
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值