JVM基础知识之垃圾收集器(二)——几种经典的垃圾收集算法

目录

目录

总述

垃圾收集算法

标记-清除算法

标记-复制算法

标记-整理算法

 总结​​​​​​​

总述

       JVM 之所以能够实现垃圾收集,是因为它在运行时会对内存中的对象进行管理和维护。JVM 中的垃圾收集器会定期扫描内存中的对象,将不再被使用的对象标记为垃圾,并将其回收。这样可以避免程序运行时出现内存泄漏等问题。

垃圾收集算法

       首先我们要先知道一般的垃圾收集算法的大致过程:垃圾收集器会定期检查存放对象的内存区域。当检查到不再使用的对象后,垃圾收集器会把这个对象进行回收。当然,这个过程还可以继续细分,可以分为标记-回收两个阶段,垃圾收集器遍历内存中的对象,把正在使用的对象进行标记,跳过没有正在使用的对象,这就是标记阶段;而在回收阶段,垃圾收集器会再次遍历所有的对象,随后识别出标记的对象和未被标记的对象,回收那些未被标记的对象。

标记-清除算法

       标记-清除算法的核心思想就是两个字:标记和清除,即先标记,再清除。标记阶段标记所有需要回收的对象,清除阶段回收被标记的对象所占用的空间。该算法最大的问题就是内存碎片严重化,后续可能发生对象不能找到利用空间的问题。

       在内存中,基于标记-清除算法,空间分为三种状态:存活对象、可回收对象、未使用空间。经过标记-清除算法后,显而易见,对于可回收对象所在的空间,将会被清理,变为未使用空间。这就是标记-清除算法实现的效果。

标记-复制算法

       前面我们已经知道标记-清除算法的基本过程,这个过程看起来非常直观准确,但也存在效率不高的问题,基于此,1969年Fenichel提出了一种可以称为“半区复制”的方法。

       核心思想就是先把内存区域分为数量相等的两个区域,一个区域1存放正在使用的对象,已经被标记的对象,以及未使用空间,而另一个区域2的空间全部都是未使用空间,当开始进行垃圾收集时,将未被清除的对象清除,仍然存活的对象移动到区域2。

       可以看到,这种算法相对于标记-清除算法,这种算法每次处理的都是二分之一的内存空间,好处是对于可回收对象并不太多的情形,这种算法每次处理的工作量不大,而且每次仅遍历一半空间,节省了很多资源。但这种算法虽然善于处理少量的可回收对象,但是因为首先就把内存空间划分了一半,这样会造成内存空间的利用率不高,而且如果遇到可回收对象占比空间比较大的情况,这种算法自身的优势也就不存在了。

标记-整理算法

       标记-整理算法是在标记-清除算法的基础上优化来的,在标记阶段和标记-清除阶段完全一致,但在清除阶段, 整理算法是先将存活对象移动到内存的一端,随后把另一端的垃圾进行清理。这里我想强调一下,所谓的“一端”指的是内存空间一个区域的起始位置,具体更精准的位置要看算法实现和内存布局。  
        相比于标记-清除算法、 标记-整理算法的优化点在于它避免了内存碎片化问题,因为清除算法只是单纯的标记,不做整理的直接去清除,而整理算法就做到了这一步,以便于内存后续再使用的时候更加高效便捷。不过高的效率也是要付出代价的,在整理阶段,这种算法不断地移动存活的对象,这其实也会导致延迟的产生,移动存活对象越多,耗时也就越长;另外,移动存活对象也会出现虚拟机需要更多的内存分配操作,这会增加垃圾收集的开销。
       所以这种算法也是有适用场景的,对于一些对于实时性要求更高的程序,内存碎片化问题往往是头号敌人,这时这种算法的优势就体现出来了。不过对于存活对象较多的应用场景,整理算法的优势就不明显了。

 总结

       目前JVM中常见的垃圾回收算法:标记-清除、标记-复制、标记-整理算法都是为了解决内存管理问题而产生的,以确保程序能够正常运行。本文只是概略地介绍了这三种算法的基本思想,更加细化详细的细节,可以在我的以后文章看到。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值