从原理聊JVM(二):从串行收集器到分区收集开创者G1
2023-04-24 10:24:44 来源:博客园

作者:京东科技康志兴

1 前言

随着Java的进化过程,涌现出各种不同的垃圾回收器,从串行执行到并行执行,从高吞吐到低延迟,终极目标就是让开发人员专注于程序的代码书写而无需关注内存管理。

JDK早期出现的垃圾回收器通常单独作用于不同分代,到后期出现的G1开始,才可以进行全区域收集。


【资料图】

关于垃圾回收器的基础知识请翻看前一篇:从原理聊JVM(一):染色标记和垃圾回收算法

2 串行收集器(Serial)

比较老的收集器,单线程,所收集时必须暂停应用的工作线程,直到收集结束。但和其他收集器的单线程相比更加简单、高效

作用于新生代的收集器叫Serial,采用标记复制算法;作用于年老代的收集器叫Serial Old,采用标记整理算法。

3 并行收集器(Parallel)

多条垃圾收集线程并行工作,在多核CPU下效率更高,但应用线程仍然处于等待状态。

并行收集器也分为ParNewParallel Old。可以理解为它们就是Serial和Serial Old的多线程并行版本,甚至部分代码进行了复用。

ParNew较为流行的原因是因为除了Serial只有它能和CMS搭配使用。但自JDK9开始,由于更先进的G1的出现,官方直接取消了单独指定ParNew的参数-XX:+UseParNewGC,使其并入了CMS收集器,成为它专门处理新生代的组成部分。

而Parallel Old则搭配新生代收集器ParallelScavenge成为名副其实的“吞吐量优先”的搭配组合。

4 ParallelScavenge

ParallelScavenge收集器是面向新生代的垃圾回收器,它和ParNew其实非常类似,使用标记复制算法并行收集。区别在于二者关注点不同,ParalletScavenge的目标是达到一个可控制的吞吐量(Throughput),更高的吞吐量意味着最大限度的使用处理器的资源来缩短整体的垃圾回收时间。ParalletScavenge有两个重要参数:

-XX:MaxGCPauseMillis

收集器将尽力保证内存回收花费的时间不超过用户设定值。但这是以牺牲吞吐量为代价的,要求用更短的时间来完成垃圾收集,那么系统就需要降低新生代大小,新生代变小了自然垃圾回收会更加频繁,每次垃圾回收都有很多必要工作(比如等待所有线程到达安全点),那么更频繁的垃圾回收就导致了整体吞吐量的降低。

-XX:GCTimeRatioGCTimeRatio

是垃圾收集时间占总时间的比率,换句话说:其表示运行用户代码时间是GC运行时间的X倍。比如默认为99,则垃圾收集时间占比应该1/(1+99)。这个数越低,运行用户代码时间占比越低。

ParallelScavenge收集器还可以通过参数(-XX:+UseAdaptiveSizePolicy)来激活自适应调节策略。激活后,就不需要人工指定新生代的大小(Xmn)、Eden与Survivor区的比例(XX:SurvivorRatio)、晋升年老代对象大小(XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。

5 CMS收集器(Concurrent Mark Sweep)

CMS收集器是缩短暂停应用时间(Low Pause)为目标而设计的,最开始CMS仅仅是年老代收集器,后来将ParNew并入作为其年轻代收集器。

相较上述收集器,CMS是第一个无需全程STW而允许部分阶段并发执行的收集器。

垃圾回收实际上主要是两个阶段:识别垃圾和回收垃圾,CMS在这两个阶段分别做了努力来降低停顿:

识别垃圾

CMS将标记过程打散,并将主要的染色标记过程和用户线程同步进行,并通过增量更新方式解决了引用切换带来的漏标的问题。

垃圾回收

CMS采用清除算法,相比复制和整理,清除算法由于仅处理死亡对象所以不需要任何停顿。

CMS运行步骤

具体来说,CMS整个过程分为4个步骤:

1. 初始标记(Initial Mark)[STW]

初始标记只是标记一下GC Roots能直接关联到的对象,速度很快。

2. 并发标记(Concurrent Marking)

并发标记阶段是标记可回收对象。

3. 重新标记(Remark)[STW]

重新标记阶段则是为了修正并发标记期间因用户程序继续运作导致标记产生变动的那一部分对象的标记记录,这个阶段暂停时间比初始标记阶段稍长一点,但远比并发标记时间短。

CMS用增量更新来做并发标记,也就是说并发标记过程中,如果某个已经标记为存活的对象增加了对非存活对象的引用,那么将其标记为灰色,然后在重新标记阶段将这一部分对象重新扫描。

4. 并发清除(Concurrent Sweep)

清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。

优点

由于整个过程中消耗最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以,CMS收集器内存回收与用户一起并发执行的,大大减少了暂停时间。

缺点

1. 处理器资源敏感

垃圾回收的线程能够与用户线程同时执行,这样虽然不会导致STW,但是由于分摊了处理器的计算资源从而导致应用程序变慢,降低了总吞吐量。

2. 内存敏感

当垃圾回收和用户线程在同步运行时产生的垃圾,由于已经过了标记阶段所以不会标记后清除,这部分垃圾只能等到下一次GC时才会被清除,这就是浮动垃圾问题。

而且由于垃圾回收和用户线程同步运行,所以不能等堆满了再GC,而是需要预留一部分内存来保证GC过程中用户线程仍有可用内存。为了降低GC频率,只能等垃圾攒多一点再触发GC,那么GC时可供用户线程使用的内存就不多了。

如果GC尚未结束用户线程分配内存失败,这个情况叫做“并发失败”,这时虚拟机会降级使用Serial Old来重新进行一次高吞吐的年老代收集,这样停顿时间就长了。

线上环境应根据实际情况来调整触发GC的内存使用阈值,该参数为:-XX:CMSInitiatingOccupancyFraction

3. CMS基于标记清除算法,所以内存碎片过多后,会频繁触发Full GC,且不可避免。CMS会在若干次触发后进行一次内存碎片的合并整理,内存整理过程涉及存活对象的移动,(在Shenandoah和ZGC出现前)无法并发。

6 G1收集器(Garbage First)

G1收集器相比上述垃圾回收器有了里程碑式的创新,它将堆内存划分多个大小相等的独立区域(Region),并且能建立“停顿时间模型”,使暂停时间可控,并尽量将-XX:MaxGCPauseMillis(默认200ms)作为停顿目标。根据Oracle官网的描述,G1是一个“软实时”的收集器,只是尽量保证在目标停顿时间内完成垃圾收集工作,但不能确保一定:

It is important to note that G1 is not a real-time collector. It meets the set pause time target with high probability but not absolute certainty.

能预测的原因是它能避免对整个堆进行全区收集,而是将整个堆分为若干个小的区域(Region),每个Region是单次垃圾回收的最小单元。在系统运行过程中,G1跟踪各个Region里的垃圾堆积价值大小(所获得空间大小以及回收所需时间),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region,从而保证了再有限时间内获得更高的收集效率。这也是Garbage First名称的由来。

G1的分代模型

G1也分为年轻代和年老代,但不是固定划分,而是每个Region根据运行情况动态划分。

G1还有一个特殊的区域叫Humongous,G1将超过了一个Region容量一半的大对象,都存放在Humongous区域中,如果对象超过了Region大小,则存放在N个连续的Humongous Region中。G1的大多数行为都把Humongous Region作为老年代的一部分来进行看待。

TAMS(Top at mark start)

为了保证垃圾回收过程中的同时Region也能够被使用,G1为每一个Region设计了两个名为TAMS的指针,分别是Previous TAMS(PTAMS)、Next TAMS(NTAMS)。在并发标记阶段开始前,TAMS指针指向Region内占用内存的边界。在并发标记阶段中,G1默认指针之上的对象为存活对象不去进行标记,而对象分配时,用户线程直接在指针之上分配。这就保证了扫描行为和对象分配互不干扰。

G1如何判定Region的“价值”

G1运行期间会收集每个Region的价值信息,比如回收耗时、记忆集的脏卡数量等,通过计算得出每个Region回收的性价比。G1的停顿预测模型就是通过这些信息,找出在用户预期时间内获得更高回收收益的Region组合。

Remembered Sets

G1堆中的每一个Region都有一份Rememberd Set,也叫RSet,它的作用就是为每一个Region记录哪些Region对其含有引用。

RSet的更新需要线程同步处理,由于对象引用变更非常频繁,如果同步写卡表消耗非常大,所以通常会把更新信息存入队列中再异步更新RSet,这个队列就叫Dirty Card Queue

G1的垃圾回收过程

当Eden中无法分配对象时,触发Young GC。

当年老代占比到达45%时,等待下一次Young GC时进行并发标记。

并发标记结束后马上执行Mixed GC。

当Mixed GC对内存的清理速度赶不上分配新对象的速度时触发Full GC,G1的Full GC将使用单线程(JDK11后改为多线程)执行标记整理算法,所以耗时巨大。

G1的Young GC触发时机

当JVM无法在Eden区分配对象时。

回收范围

Eden区和Survivor区

运行过程(所有阶段均STW)

1. 根扫描

将所有Eden区中的GC Root和RSet记录的外部引用作为扫描存活对象的入口。

2. 更新RSet

通过Dirty Card Queue中的card更新RSet,保证RSet能准确反应老年代对该Region是否存在引用。

3. 处理RSet

将Eden区中被RSet指向的对象标记为存活对象。

4. 对象复制

判断存活对象的年龄,如果未达到“阈值”,则复制到一个Surviver区中,否则复制到Old区中。如果Surviver空间不够,则将部分对象直接复制到Old区中。

5. 处理引用

处理软引用、弱引用、虚引用等,最终清空全部Eden区。这时清理过的内存空间没有内存碎片。

G1的Mixed GC触发时机

年老代占用空间超过整个堆的45%(可通过参数-XX:InitiatingHeapOccupancyPercent进行设置)

事实上,并不会立刻触发,而且等待下一次Young GC,同步进行初始标记步骤。

回收范围

被并发标记过的Region,这些Region是G1通过价值测算动态选中的。

运行过程

1. 初始标记(Initial Marking)[STW]

标记GC Roots直接关联的对象,并修改TAMS指针的值。值得注意的是,这一阶段并不单独执行,而是在Minor GC时同步完成。所以实际上这个阶段没有额外停顿。

2. 并发标记(Concurrent Marking)

与用户线程并发执行,顺着GC Root递归标记。标记完成后,重新扫描SATB记录的有引用变动的对象。如果这时发现空的Region则直接将其清空。

3. 重新标记(Remark)[STW]

由于并发标记是并发执行,并发标记结束后,仍然存在少量的引用变动的对象,所以在这个阶段可以STW来处理这部分遗留的对象。并且开始计算所有Region的活跃度。

4. 清理(Clean Up)[STW]

根据用户期望的停顿时间来制定回收计划,选择全部是非存活对象的Old区和回收收益较高的Region加入回收集。清空记忆集。重置已经被清理的空的Region(这一步是非STW的)。

5. 拷贝(Coping)[STW]

将回收集其中的存活对象复制到空的Region中,最后清空这些旧的Region。

这个阶段的算法和Young GC完全一致,但默认分8次执行完成(可由参数-XX:G1MixedGCCountTarget设置)。所以每次清理的回收集包括Eden区、Survivor区和八分之一的Old区。低存活度(垃圾多)的Region清理的较快,所以会被G1优先回收。

混合回收并不一定要进行8次。有一个阈值-XX :G1HeapWastePercent(默认值为10%),意思是允许整个堆内存中有10%的空间被浪费,意味着如果发现可以回收的垃圾占堆内存的比例低于10%,则不再进行混合回收。

优点

G1相比较之前的垃圾回收器最大的变化是通过化整为零的思路,将堆分为若干个小的Region来减少GC的范围,从而达到“低延迟”的目的。

并且G1的垃圾回收过程采用标记复制的算法,避免了空间碎片化的问题。

缺点

1.内存占用较高,由于G1分区比CMS更多,每个Region都需要建立卡表。其中新生代对象变动频繁,又加大了卡表维护的成本。

2.G1不仅需要通过写前屏障来更新卡表,还需要写后屏障来跟踪并发时的指针变化以实现快照搜索算法(SATB)。这样虽然相比增量更新算法能够减少并发标记和重新标记阶段的消耗,但是用户程序运行时的计算负载就高了。

3.G1和CMS同样具有“并发回收”的能力,所以垃圾回收的速度如果跟不上用户创建新对象的速度,那么就会触发一个Full GC来获取更多内存。通常把期望停顿时间设置为一两百毫秒或者两三百毫秒会是比较合理的。

最佳实践

1.不要设置年轻代大小年轻代大小应当由G1自行控制,设置为固定值将覆盖暂停时间目标

2.暂停时间目标不要过于严苛G1为了Young GC能够缩短时间需要减少Eden区的个数,那么Young GC就会更加频繁。Mixed GC想要达到停顿目标就需要减少回收的垃圾数量,如果回收速度低于新对象分配速度将引起Full GC。

3.CMS和G1的选择目前在小内存应用上CMS的表现大概率仍然要会优于G1,而在大内存应用上G1则大多能发挥其优势,这个优劣势的Java堆容量平衡点通常在6GB至8GB之间。

7 总结

在GC的选择上,同样是“没有银弹”,不同的收集器有着各自的特点和适用场景,即使是Epsilon也会在特定场合下发挥作用。我们应针对不同的业务特征和系统情况选择最合适的垃圾回收器,而不是一味求新。

参考:

1.《深入理解Java虚拟机》 by 周志明

2.Getting Started with the G1 Garbage Collector

从原理聊JVM(二):从串行收集器到分区收集开创者G1

2023-04-24

中建+湖北文旅建发联合摘得北京大兴共有产权住房项目用地

2023-04-24

天天简讯:昆明理工大学研究生分数线_云南大学研究生分数线

2023-04-24

环球热议:安彩高科董秘回复:公司正在投资建设硅基材料石英砂矿石加工项目

2023-04-24

库里32分福克斯38分 勇士险胜国王扳成2-2

2023-04-24

前沿资讯!万峰湖镇天气预报_万峰湖天气

2023-04-24

又一巨头,申请破产保护! 环球快消息

2023-04-24

环球速读:新一周星象+开运提点 || 射手双鱼狮子水瓶要去突破,双子处女金牛天蝎提防水逆效应

2023-04-24

“天天都是618”,电商行业是否已无需“造节”?

2023-04-24

双向可控硅测量教程_双向可控硅测量|每日精选

2023-04-24

居民自编自导拍摄短片,呼吁大伙重视“国家安全”

2023-04-24

环球实时:is曲线讲解_is曲线

2023-04-24

欧能达

2023-04-24

焦点观察:短轴褶皱

2023-04-24

python-Django-文件上传(二)

2023-04-23

2023年长三角医学创新转化峰会合肥召开|短讯

2023-04-23

setlayout什么意思_setlayout

2023-04-23

Consul 的架构和设计思路

2023-04-23

江岸区消防验收中心主动服务 保民生项目落地|热文

2023-04-23

智能财务领航者论坛在深举办,共商世界一流财务管理建设之道

2023-04-23

深兰科技:正在开发面向个人数字化的硅基知识大模型

2023-04-23

中档汽车十大品牌排名前十_中档汽车十大品牌

2023-04-23

四季豆怎么炒够味(四季豆怎么炒啊)-当前动态

2023-04-23

4月23日富艺珠宝黄金575元/克 金条553元/克

2023-04-23

23南航集SCP002今日发布发行公告 焦点关注

2023-04-23

贝蒂希金斯年轻时照片_贝蒂希金斯

2023-04-23

桂台同胞现场体验“东方式狂欢”广西宾阳舞炮龙文化

2023-04-23

全球最新:厮杀激烈的餐饮赛道,仍是创业的好选择

2023-04-23

宜宾康润环境科技有限公司61%股权拟转让

2023-04-23

适合懒人开的少投资的店有哪些 懒人开什么店赚钱呢 世界百事通

2023-04-23

环球最资讯丨关于中国女排决战塞尔维亚的结果 你知道多少?_每日关注

2023-04-23

日产新奇骏仪表盘说明书,新奇骏仪表盘功能介绍

2023-04-23

成都限购条件和购房资格

2023-04-23

当前动态:森林体育嘉年华黑科技涌现 TANGO 成下一个运动新风口

2023-04-23

湖人又赢了!詹姆斯25分,替补奇兵10中6砍16分,莫兰特空砍45分

2023-04-23

甩客、绕路、违规计价!济南通报出租车整顿典型案例-全球信息

2023-04-23

天天日报丨“功夫”小将 齐聚“梅江”

2023-04-23

社保转移对以后领取养老金有什么影响?社保转移后影响退休金吗? 天天看热讯

2023-04-23

商务部:将继续积极推进贸易数字化国际规则谈判进程

2023-04-23

世界首台兆瓦级高温超导感应加热装置投用 能效转化率提升一倍

2023-04-23

家门口就业 挣钱顾家“两不误”-今日热讯

2023-04-23

罗翔如何成为“法学界的郭德纲”?俞敏洪“爆料”:是新东方训练出来的!|报道

2023-04-23

每日聚焦:持续构建有温度的和谐用工环境,这个培训班举办

2023-04-23

观焦点:我为古籍做“微创”

2023-04-23

北京买房:理清思路,购房建议803

2023-04-23

“超级大脑”进万家要过三关 当前消息

2023-04-23

今日精选:dnf天界怎么去

2023-04-23

关键时刻掉链子,这是阿森纳的宿命? 全球资讯

2023-04-23

环球微资讯!照片尺寸处理软件下载(照片尺寸处理软件)

2023-04-23

当前速读:热带季风气候特点是什么_热带季风气候特点

2023-04-23

世界速讯:“世界地球日”投放鱼苗

2023-04-23

swum读音_swum-热闻

2023-04-23

穿越2400年的中国之声 资讯

2023-04-23

【独家】第二届中国(武汉)文化旅游博览会开幕

2023-04-23

地球凌日现象_地球凌日 当前播报

2023-04-23

穆里尼奥有哪些独特的魅力?为什么只有他能带领罗马重回巅峰?

2023-04-23

最新:齐心协力!76人篮板54-38领先篮网16个 前场板15-5

2023-04-23

我国全面完成生态保护红线划定工作 切实加强监管 每日快讯

2023-04-23

重点聚焦!poison是什么牌子香水-poison是什么意思

2023-04-23

热消息:春季饮食的小常识有哪些_春季饮食的小常识

2023-04-23

今热点:丰台青塔居住用地吸引40余家房企参与预审 建筑规模5.2万方

2023-04-23

潮气量_关于潮气量介绍_环球百事通

2023-04-23

幽字的部首是山吗_幽字的部首 世界最资讯

2023-04-22

西安国际港务区开展2023年全国肿瘤防治宣传周活动

2023-04-22

广期所副总经理曹子海

2023-04-22

视讯!浏览器页面大小快捷键_浏览器页面大小设置

2023-04-22

巫溪县气象局发布大风蓝色预警【Ⅳ级/一般】

2023-04-22

2023年4月22日雅思考试成绩单寄送时间

2023-04-22

天天观察:太白县气象台发布道路结冰黄色预警【Ⅲ级/较重】

2023-04-22

环球热头条丨面试培训机构哪个好杭州_面试培训机构哪个好

2023-04-22

广东事业单位年度招聘开始 符合条件的港澳居民可报考

2023-04-22

瑞媒:瑞信危机下瑞士已不再是“银行业国家” 制药、大宗商品成经济引擎

2023-04-22

今日热议:纪录片《金中都》:第一集《谋水营城》

2023-04-22

天天观速讯丨梦见自己拉大便在地上 已婚妇女梦见自己拉大便在地上

2023-04-22

股票中的七不买三不卖是什么意思_股票七不买三不卖是那几句话_环球新动态

2023-04-22

我脑子巨好用好玩吗 我脑子巨好用玩法简介

2023-04-22

望城经开区赴“蓉”引才,搭建进校直聘“快车道”

2023-04-22

非想天则出招表_非想天 世界微速讯

2023-04-22

QQ空间登陆 最新消息

2023-04-22

老里:相信恩比德本有可能被驱逐 但无论发生什么都会准备好G4

2023-04-22

《帐篷营业中》阵容官宣 趣味集结同好释放情绪焦虑 环球要闻

2023-04-22

税务微剧场丨小规模纳税人减免增值税政策助力郝老板梦想再起航!_世界热消息

2023-04-22

世界速讯:做好换帅准备,泰山队新教练人选浮现,前国足主帅+名宿 郝伟栽了

2023-04-22

经营有道!李春江在珠三角拥很多房产,当包租公,实现财务自由

2023-04-22

华中科技大学远程与继续教育学院地址_华中科技大学远程与继续教育学院

2023-04-22

环球报道:流云剑神传好玩吗 流云剑神传玩法简介

2023-04-22

河南最浪漫的花城,随口一说就有7个蔷薇花墙,其中有一个最美丽 全球报道

2023-04-22

无间:大结局花向雨自杀,陆风杀死闪官后娶蓝冰,生下女儿陆念雨

2023-04-22

办得好|建议小区优化车辆出入口 青海西宁:已调整到位 速递

2023-04-22

​活力夜中国丨点亮经济新“夜”态 探访热闹繁忙的港口之夜

2023-04-22

智能纺织品设计与应用_对于智能纺织品设计与应用简单介绍

2023-04-22

世界短讯!外围政策影响小 投资者不必担忧

2023-04-22

当前热议!工龄认购认购房产必须办理产权证吗

2023-04-22

中伏吃什么好?

2023-04-22

视讯!《闪电侠》中国内地定档!6月16日上映

2023-04-22

恒指夜期收盘(4.22)︱恒生指数夜期(4月)收报20009点 低水67点 焦点报道

2023-04-22

黄浦“五五购物节”聚焦首发经济、品牌经济、夜间经济

2023-04-22

如何拉人进微信群引流_如何拉人进微信群

2023-04-22

2023版“沪惠保”预计5月中上旬推出 监管部门已开会研究产品方案|天天观察

2023-04-22

【重实干 务实功 求实效】阿拉善盟——风电光伏项目建设快速推进 天天热资讯

2023-04-22