JVM四种垃圾回收算法

发布于:2022-12-29 ⋅ 阅读:(193) ⋅ 点赞:(0)

标记-清除算法

正如它的名字一样,它分为两个操作:标记清除
从根节点GC ROOT开始往下找,当一个对象脱离了根节点的时候,也就是这个对象没有一条可以到达根节点的路径,我们就将该对象标记为一个垃圾对象,就如下图中的B和E对象。
在这里插入图片描述

标记:
在这里插入图片描述

再标记完成之后,就开始执行清除的操作了。在这里插入图片描述

这种方式的缺点:

  • 需要进行两个操作,标记和清除,效率低;
  • 在清除对象之后,会导致内存空间不连续的问题,如上图所示,假设现在需要存放一个更大的对象,本来两个格子的空间是够的,但是这些空间不连续,一个格子又存放不下这个对象。

复制算法

这种算法的原理是采用了两块内存空间,或者可以说是将一块内存空间分为了两块。但是实际上我们还是使用一块内存空间。

  • 首先还是先从我们的GC ROOT根节点开始往下找,先标记出需要回收的垃圾对象
    在这里插入图片描述
  • 将存活的对象复制到另一块内存空间中
    在这里插入图片描述
  • 然后再把原内存空间中的内容一次性清理掉

缺点:

  • 比其它方式多占用一块内存空间;
  • 需要回收复制移动对象。

现在很多商业的虚拟机都是采用这个方式来回收新生代的。 因为新生代中存放的对象大多数都是存活时间很小的,也就是说存活下来的对象很少(98%都会被垃圾回收),所以在复制移动的时候不需要对大量的对象进行操作。

也可以看我的另一篇文章: 分代回收算法之新生代垃圾回收流程https://blog.csdn.net/sunao1106/article/details/126693446?spm=1001.2014.3001.5502

标记-整理算法

在上面也提到了,复制算法适用于新生代,但是不适用于老年代,因为在老年代中,大部分对象都是存活率比较高的,如果使用复制算法,将会执行多次的复制操作,而且要多分配一个内存空间出来。

标记-整理算法的第一步也是先对垃圾对象进行标记,和标记-清除法一样,但是下一步并不是将标记的垃圾对象直接进行清除,而是将存活的对象收集到一片连续的区域,也就是将它们都靠在一起,然后在清除标记的垃圾对象。
标记:
在这里插入图片描述
将存活的对象像一端移动:
在这里插入图片描述
删除标记的垃圾对象:
在这里插入图片描述

分代收集法

在当前的商业虚拟机中都是采用这个方法来进行垃圾回收的,它是根据对象的存活周期去划分不同的内存区域,比如,在JVM中,将堆分为新生代和老年代。

然后再根据这些代的特点,采用不同的算法(上述讲的三种)进行垃圾回收。比如在新生代中,对象的存活率比较低,就会采用复制算法;在老年代中,对象的存活率较高,就会采用标记-清除算法或者标记-整理算法。

在新生代中又分为Eden区、survivor from和survivor to,这样做的目的就是为了去使用复制算法进行垃圾回收。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到