JVM面试必问:G1垃圾回收器
摘要:G1垃圾回收器是一款主要面向服务端应用的垃圾收集器。
本文分享自华为云社区《JVM面试高频考点:由浅入深带你了解G1垃圾回收器!!!》,原文作者:Code皮皮虾 。
G1垃圾回收器介绍
G1垃圾回收器是一款主要面向服务端应用的垃圾收集器。作为垃圾回收器技术发展史上里程碑的成果,G1垃圾回收器不同于以往的垃圾回收器,首先是思想上的转变,如下图:
G1对于Java堆的划分

上面的图,小伙伴们第一次看可能不咋明白,因为各位还不了解G1,看看下面的话,应该就差不多了。
G1垃圾回收器对于Java堆区域的划分不同于以往我们对Java对区域划分的认知
以往对于Java堆区域的划分为:新生代和老年代,新生代又划分为 Eden区和 Survivor区,Survivor区又分为 from区和 to区。

但是现在,G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆空间划分为多个大小相等的独立区域(Region),每个Region都可以成为 Eden空间、Survivor空间、老年代空间。
这种思想上的转变和设计,使得G1可以面向堆内存任何部分来组成回收集来进行回收,衡量标准不再是它属于哪个分代,而是哪块内存存放的垃圾最多,回收收益最大,这就是G1收集器的 Mixed GC模式,即混合GC模式。
Region还有一类特殊的 Humongous 区域,专门用来存储大对象。G1认为只要大小超过了一个Region容量一半的对象即可判定为大对象。如果是那些超过了整个Region容量的超大对象,将会放在连续 N 个 Humongous Region区域。
Region的取值范围为 1M ~ 32M
Region的默认个数为 2048个
-XX:G1HeapRegionSize = N
G1这么做看起来是由一种焕然一新的感觉,但细心的小伙伴可能已经发现,如果 Region之间存在跨区引用对象,那这些对象如何解决?
- 不管是G1还是其他分代收集器,JVM都是使用 记忆集(Remembered Set) 来避免全局扫描。
- 每个Region都有一个对应的记忆集。
- 每次Reference类型数据写操作时,都会产生一个 写屏障(Write Barrier)暂时去终止操作
- 然后检查将要写入的引用 指向的对象是否和该Reference类型数据在不同的 Region(其他收集器:检查老年代对象是否引用了新生代对象)
- 如果不同,通过 卡表(Card Table)把相关引用信息记录到引用指向对象的所在Region对应的记忆集(Remembered Set) 中
- 当进行垃圾收集时,在GC Roots枚举范围加上记忆集;就可以保证不进行全局扫描了。
G1的记忆集可以理解为一个哈希表,Key就是别的Region的起始地址,Value就是卡表的索引号集合。

因为G1将Java堆划分为一个个Region的缘故,而Region数量相比于传统分代数量明显多得多,所以G1相比于传统的垃圾回收器来说,需要消耗相当于Java堆容量 10%~ 20%的额外空间来维持收集器的工作。
G1 垃圾回收器工作流程
- 初始标记(Initial Marking):这阶段仅仅只是标记GC Roots能直接关联到的对象并修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确的可用的Region中创建新对象,这阶段需要停顿线程,但是耗时很短。而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际并没有额外的停顿。
- 并发标记(Concurrent Marking):从GC Roots开始对堆的对象进行可达性分析,递归扫描整个堆里的对象图,找出存活的对象,这阶段耗时较长,但是可以与用户程序并发执行。当对象图扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象。
- 最终标记(Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的 SATB 记录。
- 筛选回收(Live Data Counting and Evacuation):负责更新 Region 的统计数据,对各个 Region 的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划。可以自由选择多个Region来构成会收集,然后把回收的那一部分Region中的存活对象==复制==到空的Region中,在对那些Region进行清空。
除了并发标记外,其余过程都要 STW
G1和CMS的区别
- G1从整体上来看是 标记-整理 算法,但从局部(两个Region之间)是复制算法。而CMS是 标记-清除算法 所以说,G1不会产生内存碎片,而CMS会产生内存碎片
- CMS使用了 写后屏障来维护卡表,而G1不仅使用了写后屏障来维护卡表,还是用了 写前屏障来跟踪并发时的指针变化情况(为了实现原始快照)。
- CMS对Java堆内存使用的是传统的 新生代和老年代划分方法,而G1使用的全新的划分方法。
- CMS收集器只收集老年代,可以配合新生代的Serial和ParNew收集器一起使用。G1收集器收集范围是老年代和新生代。不需要结合其他收集器使用
- CMS使用 增量更新解决并发标记下出现的错误标记问题,而G1使用原始快照解决
JVM面试必问:G1垃圾回收器的更多相关文章
- JVM学习——G1垃圾回收器(学习过程)
JVM学习--G1垃圾回收器 把这个跨时代的垃圾回收器的笔记独立出来. 新生代:适用复制算法 老年代:适用标记清除.标记整理算法 二娃本来看G1的时候觉得比较枯燥,但是后来总结完之后告诉我说,一定要慢 ...
- 面试必问:JVM类加载机制详细解析
前言 在Java面试中,简历上有写JVM(Java虚拟机)相关的东西,JVM的类加载机制基本是面试必问的知识点. 类的加载和卸载 JVM是虚拟机的一种,它的指令集语言是字节码,字节码构成的文件是cla ...
- G1垃圾回收器在并发场景调优
一.序言 目前企业级主流使用的Java版本是8,垃圾回收器支持手动修改为G1,G1垃圾回收器是Java 11的默认设置,因此G1垃圾回收器可以用很长时间,现阶段垃圾回收器优化意味着针对G1垃圾回收器优 ...
- 一线大厂Java面试必问的2大类Tomcat调优
一.前言 最近整理了 Tomcat 调优这块,基本上面试必问,于是就花了点时间去搜集一下 Tomcat 调优都调了些什么,先记录一下调优手段,更多详细的原理和实现以后用到时候再来补充记录,下面就来介绍 ...
- G1垃圾回收器
垃圾回收器的发展历程 背景 01.G1解决的问题 G1垃圾回收器是04年正式提出,12开始正式支持,在17年作为JDK9默认的垃圾处理器. 在04年的时候,java程序堆的内存越来越大,从而导致程序中 ...
- linux驱动工程面试必问知识点
linux内核原理面试必问(由易到难) 简单型 1:linux中内核空间及用户空间的区别?用户空间与内核通信方式有哪些? 2:linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化, ...
- 互联网公司面试必问的Redis题目
Redis是一个非常火的非关系型数据库,火到什么程度呢?只要是一个互联网公司都会使用到.Redis相关的问题可以说是面试必问的,下面我从个人当面试官的经验,总结几个必须要掌握的知识点. 介绍:Redi ...
- 【面试必问】python实例方法、类方法@classmethod、静态方法@staticmethod和属性方法@property区别
[面试必问]python实例方法.类方法@classmethod.静态方法@staticmethod和属性方法@property区别 1.#类方法@classmethod,只能访问类变量,不能访问实例 ...
- 互联网公司面试必问的mysql题目(下)
这是mysql系列的下篇,上篇文章地址我附在文末. 什么是数据库索引?索引有哪几种类型?什么是最左前缀原则?索引算法有哪些?有什么区别? 索引是对数据库表中一列或多列的值进行排序的一种结构.一个非常恰 ...
- 互联网公司面试必问的mysql题目(上)
又到了招聘的旺季,被要求准备些社招.校招的题库.(如果你是应届生,尤其是东北的某大学,绝对福利哦) 介绍:MySQL是一个关系型数据库管理系统,目前属于 Oracle 旗下产品.虽然单机性能比不上or ...
随机推荐
- 20.1 OpenSSL 字符BASE64压缩算法
OpenSSL 是一种开源的加密库,提供了一组用于加密和解密数据.验证数字证书以及实现各种安全协议的函数和工具.它可以用于创建和管理公钥和私钥.数字证书和其他安全凭据,还支持SSL/TLS.SSH.S ...
- Session入门实例
session对象(是JSP的9大内置对象之一): (1)session代表一次用户会话:从客户端浏览器连接服务器开始,到客户端浏览器与服务器断开为止,这个过程就是一次会话. (2)session作用 ...
- [OpenWrt]软路由H28K开启USB无线教程
0x01 背景 H28K软路由带了一个USB2.0的接口,官方说是支持USB无线的:于是就网购了USB转WIFI的设备(芯片:RTL8811CU),拿到手后开心的插上去,发现没有任何反应:在Q裙中询问 ...
- [CF1264D]Beautiful Bracket Sequence
题目描述 This is the hard version of this problem. The only difference is the limit of $ n $ - the lengt ...
- 接收json数据
1.导入坐标: <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId& ...
- 微服务项目-小Q视频网
1.后台管理系统(更新中...) (1)讲师列表 (2)添加讲师 (3)导入课程分类 (4)课程分类列表 其他功能就不一一截图了,后台详细功能如下 2.前台会员系统(更新中...) (1)前台的技术栈 ...
- MybatisPlus条件查询方法全解
1.是什么? MybatisPlus通过条件构造器可以组装复杂的查询条件,写一些复杂的SQL语句,从而简化我们的开发提升我们的开发效率 # 可以简单的理解为就是我们写SQL语句时where后面的条件 ...
- LeetCode224:基本计算器(栈)
解题思路: 1.双栈模拟,一个用来存数,一个用来存操作符.需要考虑 '('后面紧跟'+'.'-'这种情况 2.递归:遇到左括号开始递归,遇到右括号结束递归,返回值. 1 class Solution: ...
- Odoo16—权限控制
odoo的权限控制是通过用户组来实现的,在用户组中配置控制权限,然后再添加用户到用户组中,从而实现对用户的访问和操作权限控制.一个用户可以属于多个用户组,用户最终的权限范围取决于所属用户组权限的并集. ...
- 在蓝图中使用flask-restful
flask-restful中的Api如果传递整个app对象,那么就是整个flask应用都被包装成restful. 但是,你可以只针对某个蓝图(django中的子应用)来进行包装,这样就只有某个蓝图才会 ...