前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM中垃圾回收相关算法 - 值得了解一下的,因为早晚得了解

JVM中垃圾回收相关算法 - 值得了解一下的,因为早晚得了解

作者头像
宁在春
发布2022-10-31 14:48:58
2690
发布2022-10-31 14:48:58
举报
文章被收录于专栏:关于Java学习@宁在春

JVM中垃圾回收相关算法 - 我想是值得你了解一下的,因为早晚得了解。😁 概要:当成功区分出内存中存活对象和死亡对象后,GC接下来的任务就是执行垃圾回收,释放掉无用对象所占用的内存空间,以便有足够的可用内存空间为新对象分配内存。目前在JVM中比较常见的三种垃圾收集算法是:标记一清除算法(Mark-Sweep)复制算法(copying)标记-压缩算法(Mark-Compact)

在这里插入图片描述
在这里插入图片描述

地点:湖南省永州市蓝山县舜河村 作者:用心笑*😀

JVM 垃圾回收相关算法

一、标记-清除算法

标记-清扫式垃圾回收器是一种直接的全面停顿算法。简单的说,它们找出所有不可达的对象,并将它们放入空闲列表Free。

1)标记:

标记的过程其实就是,遍历所有的GC Roots,然后将所有GC Roots可达的对象标记为存活的对象。

如下图:

在这里插入图片描述
在这里插入图片描述

2)清除:

清除的时候将遍历堆中所有的对象,将没有标记到的对象全部给清理掉

在这里插入图片描述
在这里插入图片描述

这里所谓的清除并不是真的置空,而是把需要清除的对象地址保存在空闲的地址列表里。下次有新对象需要加载时,判断垃圾的位置空间是否够,如果够,就存放覆盖原有的地址。

  • 如果内存规整
    • 采用指针碰撞的方式进行内存分配
  • 如果内存不规整
    • 虚拟机需要维护一个列表
    • 空闲列表分配

优点:优点就是简单理解,容易实现。内存消耗较小。

缺点:1)不管标记还是没有标记,都需要进行整体扫描一遍,效率低;2) 进行GC 时,会停止用户程序,并且时间开销大,对用户体验较差;3)垃圾回收清理出来的空间内存,内存可能是不连续的,这就可能会产生内碎片(操作系统方面知识),就需要再维护一个空列表。

二、标记-复制算法

2.1、概述:

为了解决标记 - 清除算法在垃圾收集效率方而的缺陷M.L.Minsky于1963 年发表了著名的论文, “ 使用双存储区的Lisp语言垃圾收集器CA LISP Garbage CoIIector Algorithm Using SeriaI Secondary Storage 。M.L.Minsky 在该论文中描述的算法被人们称为复制(copying) 算法, 它也被M.L.Minsky 本人成功地引入到了Lisp语言的一个实现版本中。

GC复制算法原理是把内存分为两个空间一个是From空间,一个是To空间,对象一开始只在From空间分配,To空间是空闲的。GC时把存活的对象从From空间复制粘贴到To空间,之后把To空间变成新的From空间,原来的From空间变成To空间。回收前后对比下图所示

2.2、图示

在这里插入图片描述
在这里插入图片描述

应用场景:目前JVM大都使用在新生代的垃圾回收中。

2.3、优缺点

对于任意的GC算法我们都可以从吞吐量(GC延迟),内存的分配效率,内存碎片化,堆的使用效率这个几个方面评估。

优点
  • GC复制算法只搜索并复制存活的对象,少了访问整堆和构造空闲链表的操作能够在短时间内完成GC。换言之,GC复制的吞吐量要比标记-清除要优秀,并且堆越大这种差距越明显。
  • 内存的分配效率:GC复制算法不使用空闲链表,因为分块本身就是一个连续的空间。只要新建的对象不超过剩余空间的大小,只需要移动指针即可~。所以GC复制算法的分配效率非常的高效
  • 复制过去以后保证空间的连续性,不会出现“碎片”问题。
缺点
  • 此算法的缺点也是很明显的,就是需要两倍的内存空间。
  • 复制而不是移动,意味着GC需要维护两块内存之间对象引用关系,不管是内存占用或者时间开销也不小

2.4、注意

复制算法还有一个情况:如果系统中的垃圾对象很多,复制算法需要复制的存活对象数量并不会太大,或者说非常低才行(老年代大量的对象存活,那么复制的对象将会有很多,效率会很低),所以复制算法大都是应用在新生代中的垃圾回收。

三、标记-整理算法(标记-压缩算法)

3.1、概述

复制算法的高效性是建立在存活对象少、垃圾对象多的前提下的,这种情况在新生代经常发生,老年代很难出现这种情况。

标记一清除算法的确可以应用在老年代中,但是该算法不仅执行效率低下,而且在执行完内存回收后还会产生内存碎片,所以JVM的设计者认为前两种都有问题,即提出了第三种垃圾收集算法:标记-整理算法,可以说是整合了前两种的优势。

前面标记部分同标记清除部分,不同的地方在于,标记清除中只是把可回收的对象进行垃圾回收,不会对剩余的内存空间进行整理,而标记整理则会对存活的对象进行整理,截图对比如下所示:

3.2、标记-清除与标记整理算法区别

标记-压缩算法的最终效果等同于标记-清除算法执行完成后,再进行一次内存碎片整理,因此,也可以把它称为标记-清除-压缩(Mark-Sweep-Compact)算法。

二者的本质差异在于标记-清除算法是一种非移动式的回收算法,标记-压缩是移动式的。是否移动回收后的存活对象是一项优缺点并存的风险决策。可以看到,标记的存活对象将会被整理,按照内存地址依次排列,而未被标记的内存会被清理掉。如此一来,当我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址即可,这比维护一个空闲列表显然少了许多开销。

3.3、优缺点

优点: 则是一定程度上解决了前两种算法的缺陷,1)消除了标记-清除算法当中,内存区域分散的缺点;2)不用像复制算法一样,内存减半的高额代价。

缺点:

1)从效率上讲,是不如复制算法的。

2)移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址

3)移动过程中,需要全程暂停用户应用程序。

3.4、小结

标记清除

标记整理

复制

速率

中等

最慢

最快

空间开销

少(但会堆积碎片)

少(不堆积碎片)

通常需要活对象的2倍空间(不堆积碎片)

移动对象

结论:没有最好的算法,只有最合适的算法。(不然那还有这么多算法的存在勒)

堆部分中年轻代是是使用标记-复制算法进行垃圾回收,主要是因为年轻代里的对象存活时间比较短,大都朝生夕死,一次可以清除大部分对象,这样只需要把少数对象移到另一块内存中去,效率很高。

但是在老年代中,就不一样了,老年代老年代,你一听就知道这里面对象的存活时间很长,而且大多数对象都会活很久,如果使用复制算法,每次清除的对象很少,需要移动的对象很多,效率很低。那么使用标记-整理或者标记-清除更加合适,效率也会比较高。

四、自言自语

每天的生活,慢慢变的充实,未来很长,我们一起努力!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JVM 垃圾回收相关算法
  • 一、标记-清除算法
    • 1)标记:
      • 2)清除:
      • 二、标记-复制算法
        • 2.1、概述:
          • 2.2、图示
            • 2.3、优缺点
              • 2.4、注意
              • 三、标记-整理算法(标记-压缩算法)
                • 3.1、概述
                  • 3.2、标记-清除与标记整理算法区别
                    • 3.3、优缺点
                      • 3.4、小结
                      • 四、自言自语
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档