GC算法和常见垃圾回收器

一、GC算法

GC Algorithms(常见的垃圾回收算法),找到这个垃圾之后怎么进行清除的算法 。GC常用的算法有三
种如下:
1:Copying(拷贝)
2:Mark-Sweep(标记清除)
3:Mark-Compact(标记压缩)

第一个是Copying(拷贝)。非常简单,就是把内存一分为二,分开之后呢,把有用的拷贝到下面绿色
区域,拷贝完后上面全部清掉,回收完之后就变成下面的样子了,清楚简单。
在这里插入图片描述
第二个是叫Mark-Sweep,标记、清除。就是你把它标出来,然后清掉就这么简单。首先找到那些有用
的,没用的标出来然后给它清掉。
在这里插入图片描述
第三个Mark-Compact(标记压缩)。很简单,就是把所有的东西整理的过程,清理的过程同时压缩到头上去。回收之前,有用的全往前面走,哪怕这个地方是空的我也先给你压到前面去,剩下的大块空间就全部清出来了,这个叫标记压缩,整理完成之后就是下图这样的,看着特别爽,空间又是连续的还没有碎片。
在这里插入图片描述

二、GC算法问题

三种GC算法都有一定的问题,所以没法说哪个算法更加优越,看怎么使用。
1:copy算法逻辑简单,但是有一个显而易见的问题,就是空间浪费。
2:Mark-Sweep算法也有一个明显的问题,就是容易造成内存碎片。
3:Mark-Compact算法依然有它的问题,因为设计到对象的移动,移动的时候如果是多线程还要进行同步,效率较低,好处是不会产生内存碎片。

任何一个算法都有一定的问题,因此,java堆内存采用分代模型,垃圾回收器在不同的区域采用不同的回收算法。

在这里插入图片描述

一个对象产生之后首先进入伊甸区,伊甸区经过一次垃圾回收之后进入survivor区,survivor区在经过一次垃圾回收之后又进入另外一个survivor,与此同时伊甸区的某些对象也跟着进入另外一个survivor,什么时候年龄够了会进入到old区。
MinorGC/YGC: 年轻代空间耗尽时触发。
MajorGC/FullGC: 在老年代无法继续分配空间时触发,新生代老年代同时进行回收。

三、常见垃圾回收器

在这里插入图片描述
G1和ZGC在物理上已经不分代了。

3.1 Serial

在这里插入图片描述
很简单使用单线程进行垃圾回收,GC线程工作的时候会发生STW,所有的业务线程都会停止。

3.2 Serial Old

这个用在老年代,他用的是mark-sweep的算法,用的也是单线程,和Serial一样,同样会发生STW。

3.3 Parallel Scavenge

在这里插入图片描述
理解了Serial,就很容易理解Parallel Scavenge。Parallel Scavenge采用多线程来进行垃圾回收。本质的原因是,随着服务器内存不断增大,单进程的GC有点力不从心了。

3.4 Parallel Old

  • a compacting collector that uses multiple GC threads

用在老年代,和Parallel Scavenge的组合简称PS+PO,这个也是jdk1.8默认使用的垃圾回收器。

3.5 ParNew

和Parallel Scavenge基本没什么区别,就是为了和CMS配合使用推出的。

3.6 CMS(concurrent mark sweep)

CMS是一个里程碑式的垃圾回收器,原来的垃圾回收器在工作的时候,业务线程必须STW。CMS全称是并发标记清除垃圾回收器,允许GC线程和业务线程同时进行。CMS出现的本质原因是,随着服务器内存不断增大,GC线程并不是越多效率就越高,当内存很大的时候,多线程的GC,STW的时间也会很长。但是CMS毛病非常多。以至于目前任何jdk版本默认都不是CMS
在这里插入图片描述

  1. 第一个阶段叫做CMS initial mark(初始标记阶段)。很简单, 就是我直接找到最根上的对象,其他的对象我不标记,直接标记最根上的。会发生STW,但时间会很短。
  2. 第二个是CMS concurrent mark(并发标记),据统计百分之八十的GC的时间是浪费在这里,因此它把这块最浪费时间的和我们的应用程序同时运行,这是并发标记。就是你一边产生垃圾,我这一边跟着标记但是这个过程是很难完成的。
  3. 所以最后又有一个CMS remark(重新标记)。这又是一个STW。在并发标记过程中产生的那些垃圾在重新给它标记一下,这个时候需要业务线程停一下,时间不长。
  4. 最后是一个concurrent sweep(并发清理)的过程。并发清理也有它的问题,并发清理过程也会产生新的垃圾啊,这个时候的垃圾叫做浮动垃圾,浮动垃圾就得等着下一次CMS再一次运行的过程把它给清理掉。

在第二阶段并发标记是很容易发生错标的,这里使用了著名的三色标记法。

3.6.1 三色标记法

在这里插入图片描述
如果一个对象自己已经完成标记,并且fields都完成了标记,那么这个对象就是黑色的。
如果一个对象自己标记完成,fields还没有标记,那么这个对象就是灰色的。
如果一个对象还没有被GC线程遍历到,那么这个对象是白色的。

因为业务线程是在运行中的,对象的引用有可能会发生变化,比如:
在这里插入图片描述
下一次操作系统调度GC线程进来的时候,B–>D消失,A–>D增加
在这里插入图片描述
这时候就会有问题,本来A已经标记为黑色了,不会去扫子节点,B灰色的,应该去扫子节点,但是指向子节点D的引用消失了,这时D就标记不到,成为了垃圾,这是错误的。所以当一个黑色对象,增加一个新的引用的时候,GC要把这个对象重新变为灰色,这是CMS的解决方案,这种算法叫做incremental update(增量更新)
在这里插入图片描述
CMS是一款低延迟的垃圾回收器,牺牲了一定的吞吐量。

3.7 G1

G1是一款服务端应用使用的垃圾回收器,目标是用在多核、大内存的机器上,它在大多数情况下,可以实现指定的GC暂停时间,同时还能保持较高的吞吐量。

3.7.1 分区

由于堆内存十分巨大,G1采用了分而治之的思想,也就是分区,把内存分为一小块一小块的region,从1M2M最大到32M。每一份region在逻辑上依然属于某一个分代,这个分代分为四种,第一种Old区都是放老对象的、Survivor区放存活对象的、Eden区放新生对象的、Humongous区大对象区域,对象特别大有可能会跨两个region。所以G1的内存模型已经完完全全的和以前的分代模型不一样了。region的角色并不是固定不变的。
在这里插入图片描述

3.7.2 GC

1、YGC
JVM启动时,G1先准备好Eden区,程序在运行过程中不断创建对象到Eden区,当Eden空间耗尽时,G1会启动一次年轻代回收过程。YGC时,会发生STW。需要注意的是,每次GC时,所有的新生代都会被扫描。
特别需要注意的是,根对象有可能在Old区,然后Old区可能也指向Eden区的对象,那么是否扫描新生代还要扫描整个老年代,这显然是不可取的。G1使用RSet来记录并跟踪Region间的对象引用关系,每个Region初始化时,也会初始化一个RSet,RSet记录其它Region指向本Region对象的记录。
在这里插入图片描述
上图中有三个Region,每个Region被分成了多个Card,在不同Region中的Card会相互引用,Region1中的Card中的对象引用了Region2中的Card中的对象,Region3中的Card中的对象引用了Region2中的Card中的对象,所以Region2的RSet记录了这些引用。
如果一个Old区Card中有对象指向新生代,就将它设为Dirty,只需要扫描这些Dirty的就可以了。
2、MixedGC(混合GC)
当堆内存使用达到一定值时,默认45%(-XX:InitiatingHeapOccupancyPercent),就启动了MixedGC,MixedGC即会回收新生代,也会回收部分老年代。MixedGC时和CMS一样也经历了4个阶段:

  • 初始标记 STW
  • 并发标记(三色标记法)
  • 重新标记 STW
  • 筛选回收 STW (并行)

初始标记时,会触发一次YGC。
并发标记时,会计算每个Region的对象活性,也就是存活对象的比例。
重新标记时,使用了效率更高的SATB算法,不同于CMS的增量更新。
筛选回收时,不会回收整个Old区,而是根据Region的对象活性,从中挑选几个回收价值高的Region进行回收,尽可能达到指定的GC暂停时间(-XX:MaxGCPauseMillis)。也就是说,如果GC指定暂停时间设置的比较少,那么从Old回收的Region就会比较少。

3、FGC
G1的设计初衷就是为了避免FullGC的出现,如果出现了FullGC,可以从下面两点调整:

  • 扩内存
  • 降低MixedGC触发的阈值,让MixedGC提早发生(默认是45%)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值