JVM | 垃圾清除算法


theme: channing-cyan

这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战

一、标记-清除

标记-清除(Mark-Sweep) 完整流程如下:

  • 【标记】使用可达性分析算法判断要回收的对象,并进行标记
  • 【清除】清除标记的回收的对象

标记-清除.png

如图上所示,标记-清除的缺点很明显,第一是清除掉标记的对象后,极易产生内存碎片。假如我们要给一个超大的字符串数组分配一个空间, 因为数组的内存空间是连续的,所以JVM可能找不到合适的内存去存储它,然后就会触发一下次垃圾回收。

第二就是执行效率很不可控,假如堆中大部分的对象都是可回收的,收集器要执行大量的标记、手收集操作。

二、标记-整理

标记-整理/压缩(Mark-Compact) 完整流程如下:

  • 【标记】与标记-清除的第一步不能说一模一样,只能说完全相同
  • 【整理】把所有的存活对象压缩到内存的一端
  • 【清除】清除掉边界之外所有的空间

标记整理.png

相较之于标记-清除,因为做了一次整理操作,所以垃圾对象清除后,解决内存碎片的问题,同时也不存在空间浪费的问题。是不是完美,你想多了!整理这步操作,本身会消耗资源,甚至如果内存中存活的对象很多,并且都是一些占内存空间较小的对象,并且要回收的垃圾对象很少时,垃圾收集器要移动大量的存活对象才能换取少量的内存空间,实在是不划算,这个便是标记-整理的缺点

三、标记-复制

标记-复制(copy) 完整流程如下:

  • 【内存均分】把内存分为两块区域(运行区域、保留区域),每次只是使用运行区域
  • 【标记】标记流程跟前面两种算法相同
  • 【复制】将正在运行区域中使用的存活对象复制到保留区域
  • 【清除】清除掉运行区域中的所有对象
  • 【交换空间】交换两个内存块的角色,等待下一次回收

复制8.png

标记-复制算法整个流程很像“踢皮球”,存活的对象在运行区域和保留区域被踢来踢去。这种算法的优点很明显,在大量垃圾对象的情况下,只需要复制少量的存活对象,而且并不会产生内存碎片,很好的兼顾了效率和内存碎片的问题。那是不是又完美了?并不是,每次都要预留一半的区域,很浪费,这个是典型的以空间换时间的算法。而且如果内存中存活对象多,要回收的对象少,收集器也是要复制操作多次 才能释放少量的空间,很不划算。

四、总结

三种算法的区别 算法名 | 主要优点 | 主要缺点 | | ----- | ------- | --------------------- | | 标记-清除 | 实现简单 | 清除后可能会存在内存碎片,影响分配内存效率 | | 标记-整理 | 无碎片 | 整理存在开销 | | 标记-复制 | 性能好、无碎片 | 内存利用率低 |

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值