探索G1垃圾回收器

前言

上篇JVM的文章中我们对ParNew和CMS垃圾回收器已经有了一个比较透彻的认识,感兴趣的小伙伴可以去回看一下探索ParNew和CMS垃圾回收器

今天我们继续探索垃圾回收器G1的原理,让我们开始吧!

G1的内存模型

G1是从jdk7开始出现的,在jdk9中被设为默认垃圾收集器,目标就是彻底替换掉CMS,那么为什么它可以替换掉CMS呢?

首先我们就来看看它的内存模型吧。

其实G1是可以同时回收年轻代和老年代的,他最大的特点就是把jvm堆内存拆分为了多个大小相等的Region,那么还存在年轻代和老年代吗?

答案是肯定的,不同的是新生代可能包含了某些Region,老年代也可能包含了某些Region,如下图:

到底有多少Region?每个Region有多大呢?

其实这个默认情况下是自动计算的,假如我们给定整个堆内存大小为4096M,然后使用“-XX:+UseG1GC”指定垃圾回收器为G1,此时会自动用堆内存大小除以2048,因为JVM最多可以有2048个Region,然后Region的大小必须是2的倍数。

堆内存为4096M,就会分配给每个Region 2M的内存空间。我们使用G1默认的计算方式就可以了。

当然也可以通过参数“-XX:G1HeapRegionSize”来指定Region的大小。

新生代和老年代的默认比例是多少呢?

我们知道使用ParNew和CMS垃圾回收器时,新生代和老年代的默认比例是1:2,而使用G1后,默认新生代对堆内存的初始占比是5%,这个可以通过“-XX:G1NewSizePercent”来设置初始占比,一般不需要设置。

细心的小伙伴会发现,这里说的占比是初始占比,因为系统运行的时候,JVM其实会不停的给新生代增加更多的Region,但是最多新生代的占比不会超过60%,可以通过“-XX:G1MaxNewSizePercent”来设置。

而一旦发生了垃圾回收,新生代的Region数量还会减少,所以其实新生代和老年代的占比不是一成不变的,而是动态改变的。

新生代还有eden和survivor吗?

答案是肯定的,新生代还是有eden和survivor的,只不过内存占用会随着Region的增多而增大。

G1的停顿时间控制

除了内存的变化,G1还有一个最大的变化,就是可以让我们设置一个垃圾回收的预期停顿时间,也就是说我们可以指定G1垃圾回收导致“Stop the World”的最长时间。

我们知道JVM一大痛点就是"Stop the World",尽量减少它的时间就可以做到JVM的优化。

引入G1后,我们可以自己去设定这个停顿的最长时间了,相当于直接控制了垃圾回收的性能。

G1要做到这一点就要去追踪每个Region的回收价值,那什么是回收价值呢?大家看下图:

比如两个Region中,其中一个有10M的垃圾对象,垃圾回收需要耗时1s,另一个有20M的垃圾对象,垃圾回收耗时200ms。

然后G1进行垃圾回收的时候,发现最近1小时垃圾回收已经导致了几百毫秒的系统停顿了,所以会选择回收价值高的Region进行回收,200ms的时间就能回收掉20M的垃圾对象,回收价值相对较高,所以会选择这个Region进行回收

G1控制停顿时间的思路,简单来讲就是,它会通过跟踪Region的回收价值,尽可能的保证系统停顿时间在你设定的停顿时间范围内。

G1的垃圾回收详解

上文我们了解到新生代还是有eden和survivor的,那么随着新生代占据堆内存大小的60%的时候,这个时候就会触发新生代的GC,G1也会使用之前我们说过的复制算法进行垃圾回收,进入一个“Stop the World”状态。

但是这个过程与之前的Minor GC其实是有差别的,首先回收的对象变成了带有垃圾对象的Region,然后回收的同时会根据设定的停顿时间进行价值回收,如上文所述。

什么时候进入老年代呢?

这个可以说和之前是一模一样的,简单介绍如下:

新生代躲过多次垃圾回收后会进入老年代;

GC后存活对象超过Survivor区的50%,那么会触发动态年龄判定规则,符合规则的进入老年代。

具体细节不在说明,可以参考王子之前的文章秒懂JVM的垃圾回收机制,有详细解释。

需要注意的是,G1的大对象不是存到老年代中的,而是提供了专门的Region来存放大对象。

在G1中,大对象的判断规则就是这个对象超过了一个Region大小的50%,比如Region是2M的,那如果你的对象超过了1M,就会被认定为大对象,做特殊处理。

而且如果这个大对象过大,可以横跨多个Region进行存储,如下图:

老年代具体又是怎么进行垃圾回收的呢

这个过程说起来可能稍微复杂了一点,但是它和CMS的垃圾回收过程其实是类似的。关于CMS的垃圾回收的几个阶段可以回顾王子的上篇文章探索ParNew和CMS垃圾回收器

首先我们要弄明白,什么时候会触发新生代和老年代的混合垃圾回收?

G1有一个参数“-XX:InitiatingHeapOccupancyPercent”,默认值为45%。

什么意思呢?就是说当老年代占据了堆内存的45%的Regionf的时候,就会触发混合垃圾回收。

具体流程是什么样的呢?

首先会触发一次初始标记操作,这个过程是要“Stop the World”的,对应的就是CMS的初始标记阶段,细节不再说明。

接着会进入并发标记阶段,这个阶段同样对应CMS的并发标记阶段,不再说明。

接着会进入最终标记阶段,这个阶段其实和CMS的重新标记阶段也基本一致。

最后就是混合回收阶段,这个阶段和CMS的并发清理阶段就不太一样了,这个阶段会计算每个Region中的存活对象数量,存活数量占比,还有执行垃圾回收的耗时等问题。

接着会进入“Stop the World”阶段,然后全力以赴进行垃圾回收,并尽量保证停止时间不超过我们设定好的时间,所以可能只会回收掉之前标记好的一部分垃圾对象。

为什么要叫做混合回收呢,因为它不仅仅回收的是老年代,新生代和大对象的Region也会同时进行回收,而具体回收哪些Region就要视情况而定了,根据价值回收价值G1会自己做出选择。

而混合回收是可以进行多次的,比如先停止系统,混合回收掉一部分Region,再停止系统,再执行一次混合回收。

有参数可以控制这个数量,“-XX:G1MixedGCCountTarget”参数,就是在一次混合回收的过程中,最后一个阶段执行几次,默认是8次。

为什么要这样反复多次的回收呢?

因为这样每次回收停止系统的时间都很短,在回收的间隙系统是可以正常运行的。

还有个参数“-XX:G1HeapWastePercent”,默认值是5%。

它的意思是,混合回收的时候,都是基于复制算法进行的,把Region存活的对象放入其他Region,然后清除掉本来的Region。那么当空闲的Region数量达到堆内存的5%,就会立即停止混合回收。

而通过这种复制算法回收,也不会出现像CMS标记清理算法导致的内存碎片问题。

还有个参数“-XX:G1MixedGCLiveThresholdPercent”,默认值是85%,意思就是回收Region的时候,存活的对象必须少于85%才可以被回收掉。否则存活对象太多,复制的时候成本是很高的。

如果回收失败怎么办?

如果在复制的时候发现没有空闲的Region可以承载存活的对象,那么会触发失败,立马停止系统进程,采用单线程进行标记、清理和压缩整理,空闲出一批Region,这个过程是极慢的。

总结

本文我们对G1的内存机制和垃圾回收的算法做了一个比较清晰的解释。

阅读完本文,相信小伙伴们自己可以总结出G1和CMS究竟有什么不一样了吧。

欢迎小伙伴们留言区讨论G1和CMS的区别,王子会第一时间回复。

那我们下篇文章再见。

(0)

相关推荐

  • Java虚拟机(JVM)面试题(2020最新版)

    大家好,我是CSDN的博主ThinkWon,"2020博客之星年度总评选'开始啦,希望大家帮我投票,每天都可以投多票哦,点击下方链接,然后点击'最大",再点击'投TA一票'就可以啦 ...

  • 垃圾回收

    垃圾回收GC GC的概念及意义? 概念:垃圾回收,释放jvm内存,可以在一定程度上避免OOM问题. 意义:每当我们新建对象时,jvm就会自动监控这个对象的地址大小与使用情况,通过可达性分析算法寻找不可 ...

  • 程序员登高之路——JAVA篇——2.JVM的垃圾回收

    如何判断对象死亡? 目前主流的判断对象死亡的方法有两种: 1.引用计数法: 每个对象对象包含一个引用计数器,每当对象被引用,引用计数器便加一,引用失效就减一.当对象的引用计数器为0时,则表示对象可被回 ...

  • JVM调优之垃圾定位、垃圾回收算法、垃圾处理器对比

    谈垃圾回收器之前,要先讲讲垃圾回收算法,以及JVM对垃圾的认定策略,JVM垃圾回收器是垃圾回收算法的具体实现,了解了前面的前置知识,有利于对垃圾回收器的理解. 什么是垃圾? 垃圾,主要是指堆上的对象, ...

  • 应该是全网最全的JVM知识点总结

    应该是全网最全的JVM知识点总结

  • JVM 经典垃圾收集器 —— CMS 收集器和 G1 收集器

    本文部分摘自<深入理解 Java 虚拟机第三版> CMS 收集器 1. 概述 CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器.由于大部 ...

  • G1垃圾回收器介绍与CMS区别

    G1垃圾回收器介绍与CMS区别

  • 新一代垃圾回收器ZGC的探索与实践

    很多低延迟高可用Java服务的系统可用性经常受GC停顿的困扰,作为新一代的低延迟垃圾回收器,ZGC在大内存低延迟服务的内存管理和回收方面,有着非常不错的表现. 本文从GC之痛.ZGC原理.ZGC调优实 ...

  • 7种jvm垃圾回收器,这次全部搞懂

    前言 之前我们讲解了jvm的组成结构与垃圾回收算法等知识点,今天我们来讲讲jvm最重要的堆内存是如何使用垃圾回收器进行垃圾回收,并且如何使用命令去配置使用这些垃圾回收器. 堆内存详解 上面这个图大家应 ...

  • 细节!3部分讲明白HotSpot:运行时 编译器 垃圾回收器

    细节!3部分讲明白HotSpot:运行时 编译器 垃圾回收器 代码熬夜敲2021-01-13 10:24:57 Java虚拟机 Java 虚拟机日益成为互联网大厂面试的重要内容,对于 Java 开发者 ...

  • JVM垃圾回收器及算法原理

    前言 大家在面试的时候不同程度会被问到JVM的垃圾回收,看面试官水平,有些就背个书就行,比如GC的工作原理,有哪些GC算法和回收器,分别优点和缺点等等,有些面试官估计自己也就背书水平,都没个追问:有些 ...

  • 前沿实践:垃圾回收器是如何演进的?

    阿里妹导读:上一篇<底层原理:垃圾回收算法是如何设计的?>介绍了垃圾回收的基本原理,以及若干种基本算法和优化算法,这部分内容属于垃圾回收的方法论.下面将结合业界目前垃圾回收器的发展方向,介 ...

  • JVM真香系列:图解垃圾回收器

    回复"000"获取大量电子书 不知不觉,JVM系列已经到回收算法的实现了. 本文主要内容 先普及三个概念: 并行收集:指多条垃圾收集线程并行工作,但此时用户线程仍处于等待状态. 并 ...

  • 咱们的太空上的垃圾越来越多了,以后清理也是个麻烦事啊#探索宇宙#地球#手机摄影

    咱们的太空上的垃圾越来越多了,以后清理也是个麻烦事啊#探索宇宙#地球#手机摄影

  • 戴昕:垃圾分类下,万德斯的厨余垃圾资源化模式探索

    来源:中国固废网         整理:李晓佳 垃圾分类在全国范围内的广泛推广,不仅改变着人们的生活习惯,也在逐步改变着固体废物的处理模式,对整个固废产业影响深远,尤其是对垃圾后端处理处置的影响. 2 ...