Java的几种垃圾回收算法

Java的几种垃圾回收算法


上篇讲了在堆内存中,垃圾回收器是如何辨别哪些对象可以被回收,那么回收对象的时候又是怎么样的过程呢,本篇会介绍几个常见的垃圾回收算法

在Java中,垃圾回收的核心思想主要分为两部步:

  1. 通过上篇中的可达性算法找到存货的对象
  2. 释放不再存活的对象的内存,使得程序能再次利用这块空间,即回收

垃圾回收算法的效率

在Java中,垃圾回收的过程是单独创建了一个GC线程来完成,不管是哪种垃圾回收算法,在执行垃圾回收的时候都要先将用户线程停止,这个停止的过程称为STW:Stop The World,如果STW的时间过长则会影响用户的使用体验:

用户执行代码1STW用户执行代码2STW用户执行代码3

所以判断一个垃圾回收算法是否优秀,可以从三个方面考虑:

  1. 吞吐量
    吞吐量指的是CPU用于执行用户代码与CPU执行总时间的比值,即吞吐量=CPU执行用户代码时间 / 执行用户代码时间+GC时间,吞吐量的值越高,垃圾回收的效率越高
  2. 最大暂停时间
    即STW的最大值,程序暂停时间过长会降低用户体验感
  3. 堆使用效率
    不同的垃圾回收算法对于堆的使用效率是不同的,如果对堆的使用效率越高,则需要垃圾回收的次数会越少

垃圾回收算法

目前共有四种常见的垃圾回收算法:

  • 标记清除算法
  • 复制算法
  • 标记整理算法
  • 分代垃圾回收算法

1.标记清除算法

标记清除算法的核心思想分为两类:

  1. 标记阶段:通过上篇讲述的可达性算法找到所有存活的对象,将其标记
  2. 清除阶段:将内存中的未标记存活对象进行清除回收

标记清除算法也是最早提出的垃圾回收算法,也是最简单的垃圾回收算法,首先会通过之前讲到的可达性算法,利用GC Root对象遍历引用,标记所有的存活对象,没有被GC Root找到的对象就是被认为已经不再使用的对象,则对其清除回收

GC Root对象
普通对象
对象A
对象B
对象C
对象D

红色对象是在标记阶段进行标记的对象,那么紫色对象就是没有被标记的,在清除阶段,对象D将会被回收

该方法的优点就是实现简单,并且对于堆的利用率比较高,但是缺点就是内存中会多很多碎片空间,堆内存中,需要进行回收的对象不一定是连续的,回收过后,空闲空间就会形成“这一块那一块”的情况,若是需要分配空间的话,就要遍历整个可用列表才能找到可用分配的空间

2.复制算法

复制算法把整个堆内存分为了两块:Form空间和To空间,但是这个名字不是定死的,因为在垃圾回收过程中名字会发生改变

堆内存
From
空间
To
空间

他的过程主要分为两步:

  1. 把From空间所有的存活对象全部复制到To空间
  2. 清除From空间全部对象,再将两块空间进行交换名称

这样,我们创建的对象不管在那一片空间,在垃圾回收时,只要他还存活,就会被复制到To空间中,这样From空间中只剩下了要被回收的对象,清除回收From空间后呢,再进行交换名称,这样保证To空间的内存是完全充足的,等到下次垃圾回收时,以便再把From空间的存活对象复制过去

垃圾回收
堆内存.
From空间
对象A
对象B
To空间
对象C
堆内存
To空间.
空空如也
From空间.
对象A.
对象C.

算法的优点是吞吐量高只需要遍历一次存活对象,并且也没有碎片空间,每次更名过后To空间都是一大片连续可用空间,但是他的缺点是堆使用效率不高

3.标记整理算法

标记整理算法是对于第一种算法标记清除算法的一种优化,他解决了清除过后碎片化空间的问题,他的大致过程为:

  1. 标记阶段:通过上篇讲述的可达性算法找到所有存活的对象,将其标记
  2. 整理阶段:把刚刚标记的对象全部移动到堆的一端,再进行清除操作

清除后存活的对象全部到了堆内存的一侧,而另一侧就是可用的空间,连续的空间在要为新对象分配内存时就可以依次为其分配,而不需要遍历可用列表寻找合适大小的空间的

该算法虽然解决了碎片化空间的问题,但是多次的遍历复制使其吞吐量大大降低

4.分代垃圾回收算法

分代垃圾回收算法,可以说是上面三种算法思想的组合,但是也与上面三种完全不同,他将堆内存分为了两个部分,一片是年轻代,另一片是老年代,而年轻代中又将其分为三片空间,伊甸园区幸存区S0幸存区S1

堆内存
年轻代Young区
伊甸园区
Eden
幸存区S0
幸存区S1
-
老年代
Old区

年轻代用来存放存活时间比较短的对象,老年代用来存放存活时间比较长的对象
新创建出来的对象会将他放在伊甸园区,而S0与S1来充当From区和To区的工作
该垃圾回收算法的大致过程如下:

  1. 当伊甸园区中新创建出来的对象越来越多,就会触发一次年轻代GC(Young GC),会先利用可达性算法找到存活的对象,然后再把伊甸园区和From区的存活对象复制到To区,并清除回收伊甸园区和From区,From与To进行更名操作
  2. 每次进行Young GC都会记录对象的年龄,年龄初始值为0,每GC一次就年龄+1,当一个对象的年龄达到15时,会认为他是一个长期存活对象,就把该对象复制移动到老年代区域
  3. 当老年代中空间即将饱和时,此时再有新的对象被创建,会先触发一次Young GC,如果依然空间不足,就会触发Full GC,会对整个堆内存进行垃圾回收,回收一部分老年代中的对象

目前较新的垃圾回收器使用的都是分代垃圾回收算法


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值