G1收集器详解

1.基础介绍

1.1 G1简介

Garbage First(简称G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。

G1是一款主要面向服务端应用的垃圾收集器。HotSpot开发团队最初赋予它的期望是(在比较长期的)未来可以替换掉JDK5中发布的CMS收集器。JDK9发布之日,G1宣告取代了Parallel Scavenge加Parallel Old组合,成为服务端模式下的默认垃圾收集器,而CMS则沦落被声明为不推荐(Deprecate)使用的收集器。

G1是一个实现了可控停顿时间的垃圾收集器,通过-XX:MaxGCPauseMillis参数进行设置,默认是200ms。

1.2 Region

G1开创的基于Region的堆内存布局。虽然G1也仍是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有非常明显的差异:G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。收集器能够对扮演不同角色的Region采用不同的策略去处理,这样无论是新创建的对象还是已经存活了一段时间、熬过多次收集的旧对象都能获取很好的收集效果。

image

G1中五种不同类型的Region:

  1. Eden regions(年轻代-Eden区)
  2. Survivor regions(年轻代-Survivor区)
  3. Old regions(老年代)
  4. Humongous regions(巨型对象区域,通常也被认为是老年代的一部分)
  5. Free resgions(未分配区域,也会叫做可用分区)-上图中空白的区域

Region中有一类特殊的Humongous区域,专门用来存储大对象。G1认为只要大小超过了一个Region容量一般的对象即可判定为大对象。每个Region的大小可以通过参数-XX:G1HeapRegionSize设定,取值范围为1MB~32MB,且应为2的N次幂。而对于那些超过了整个Region容量的超级大对象,将会被存放在N个连续的Humongous Region之中,G1的大多数行为都把Humongous Region作为老年代的一部分来进行看待。

因此,大对象分配空间分配区域策略可总结为:

对象大小为:<0.5个Region,存储到标记为Eden的Region中
对象大小为:0.5~1个Region,存储到标记为Humongous的Region中
对象大小为:>1个Region,存储到标记为Humongous的多个连续Region中

1.3 GC类型

  • youngGC:回收Eden区和Survivor区的内存。
  • MixedGC:包含所有年轻代以及部分老年代Region。
  • FullGC:全堆扫描。

2.运行原理

2.1 基础知识

2.1.1 记忆集(Remenbered Set,简称RSet)和卡表(Card Table)

记忆集(RSet)是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。卡表(Card Table)就是记忆集的一种具体实现,它定义了记忆集的记忆精度、与堆内存的映射关系等。关于卡表与记忆集的关系,可以用HashMap与Map的关系来类比理解。

卡表最简单的形式可以只是一个字节数组,数组中的每一个元素都对应着其标识的内存区域中一块特定大小的内存块,整个内存块被称为“卡页”(Card Page)。HotSpot中卡页大小为521字节。如果卡表标识内存区域的起始地址是)0x0000的话,数组的第0、1、2号元素,分别对应了地址范围0x0000 ~ 0x01FF、0x0200 ~ 0x03FF、0x0400 ~ 0x05FF的卡页内存块,如下图所示。

image

一个卡页的内存中通常包含不止一个对象,只要卡页内有一个(或更多)对象的字段存在着跨代指针,那就对应卡表的数组元素的值标识为1,成为这个元素变脏,没有则标识为0.在垃圾收集发生时,只要筛选出卡表中变脏的元素,旧能轻易得出哪些卡页内存块中包含跨代指针,把它们加入GC Roots中一并扫描。

因此,RSet存在的意义就是避免对象跨代引用时对整个堆内存对象的扫描,起到一种类似索引(更像空间索引)的作用。

2.1.2 原始快照(Snapshot At The Beginning,SATB)

简洁地来说,SATB是维持并发GC的一种手段,因为像CMS、G1等收集器,首先经过初始标记,然后进行并发标记,并发标记过程中,可能对初始标记的结果产生了改动,需要进行修正,分别有增量更新和原始快照两种解决方法。CMS收集器使用增量更新来纠正对象引用关系,而G1收集器使用原始快照的策略。

具体参考:

2.2 运行流程

2.1.1 初始标记

仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS指针的值,让下一阶段用户线程并发运行时,能正确地在可用地Region中分配新对象。这个阶段需要停顿线程(会产生STW),而且是借用进行Minor GC地时候同步完成的,所以G1收集器在这个阶段没有产生特别明显的停顿。

2.2.2 并发标记

从GC Root开始对堆中对象进行可达性分析,集合RSet,递归扫描堆里的对象图,找出要回收的对象,这个阶段耗时较长,但可与用户程序并发执行。当对象扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象。

2.2.3 最终标记(重新标记)

对用户线程做另一个短暂的暂停(会产生STW),用于处理并发阶段结束后仍遗留下来的最后少量的SATB记录。

2.2.4 筛选回收

负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region构成回收集,然后决定回收的那一部分Region的存货对象复制到空的Region中,再清理掉整个旧Region的全部空间。这里的曹祖哟涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。

3.总结

G1除了并发标记外,其余阶段也是要完全暂停用户线程的,换言之,它并非纯粹地追求低延迟,官方给它设定的目标是在延迟可控的情况下获得尽可能高的吞吐量,所以才能担当起“全功能收集器”的重任与期望。

G1提高效率的点有哪些:

  1. 使用RSet降低了扫描的范围。
  2. 重新标记阶段使用SATB速度比CMS的增量更新快。
  3. 清理过程中,选择部分回收价值高的Region进行清理(mixedGC),而不是所有Region,提高了清理效率。

4. 参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339