g1垃圾回收器的优缺点_调优垃圾回收器的技巧

g1垃圾回收器的优缺点

这是有关G1垃圾收集器的两部分系列文章中的第二篇。 您可以在InfoQ 2013年7月15日找到第1部分: G1:由一个垃圾收集器来全部统治

在我们了解如何调整“垃圾优先”垃圾收集器(G1 GC)之前,我们必须首先了解定义G1的关键概念。 在本文中,我将首先介绍该概念,然后讨论如何针对该概念调整G1(在适当情况下)。

记忆集

回想一下上一篇文章:记忆集(简称RSets)是按区域的条目,可帮助G1 GC跟踪指向堆区域的外部引用。 因此,现在,G1无需扫描整个堆中对区域的引用,而只需扫描其RSet。


图1:记忆集

让我们来看一个例子。 在上面的图1中,我们显示了三个区域(以灰色表示):区域1,区域2和区域3以及它们代表一组卡的相关RSet(以粉红色表示)。 区域1和区域3恰好都在引用区域2中的对象。因此,区域2的RSet跟踪对区域2的两个引用,即“拥有区域”。

有两个概念可以帮助维护RSets:

  1. 写后障碍
  2. 并发细化线程

屏障代码在写入后进入(因此称为“写入后屏障”),并有助于跟踪跨区域更新。 更新日志缓冲区负责记录包含更新的参考字段的卡。 一旦这些缓冲区已满,它们就会退役。 并发优化线程处理这些完整缓冲区。

请注意,并发优化线程通过并发更新RSets(当应用程序也正在运行时)来帮助维护RSets。 并发优化线程的部署是分层的,其中最初仅部署少量线程,然后根据要处理的已填充更新缓冲区的数量最终添加更多线程。 并发优化线程的最大数量可以由-XX:G1ConcRefinementThreads甚至-XX:ParallelGCThreads控制 。 如果并发优化线程无法跟上已填充缓冲区的数量,则更改器线程将拥有并处理缓冲区的处理-通常应避免这样做。

好,回到RSets-每个区域有一个RSet。 RSets的粒度分为三个级别-稀疏,精细和粗糙。 Per-Region-Table(PRT)是包含RSet粒度级别的抽象。 稀疏PRT是包含卡索引的哈希表。 G1 GC在内部维护这些卡。 卡可以包含从跨越与卡相关联的地址的区域到拥有区域的引用。 细粒度的PRT是一个开放的哈希表,其中每个条目代表一个引用拥有区域的区域。 该区域内的卡索引保存在位图中。 当达到细粒度PRT的最大容量时,在粗粒度位图中设置相应的粗粒度位,并且从细粒度PRT中删除相应的条目。 每个区域的粗略位图只有一位。 粗粒度图中的设置位意味着关联的区域可能包含对拥有区域的引用。

收集集(CSet)是在垃圾收集期间要收集的一组区域。 对于年轻集合,CSet仅包括年轻区域,对于混合集合,CSet包括年轻和旧区域。

如果CSet包含许多带有粗糙的RSets的区域(请注意,“ RSets的粗化”定义为RSets通过不同粒度级别的过渡),那么您将看到RSets扫描时间的增加。 这些扫描时间在GC暂停中在GC日志中表示为“ Scan RS(ms)”。 如果相对于整体GC暂停时间而言,“扫描RS”时间似乎较长,或者对于您的应用程序而言,它们看起来较高,那么在使用诊断选项-XX:+ G1SummarizeRSetStats时,请在GC日志输出中查找文本字符串“ Did xyz thinnings” (您还可以通过设置-XX:G1SummarizeRSetStatsPeriod = period来指定报告频率周期(以GC的数量为单位))。

如果您回想起前一篇文章,GC暂停输出中的“ Update RS(ms)”显示了更新RSets所花费的时间,“ Processed Buffers”显示了GC暂停期间更新缓冲区过程的计数。 如果您在GC日志中发现了问题,请使用上述选项进一步“深入研究”问题。

这些选项还可以帮助确定更新日志缓冲区和并发优化线程的潜在问题。

-XX:+ G1SummarizeRSetStats的样本输出,其周期设置为一个-XX:G1SummarizeRSetStatsPeriod = 1:
并发RS 处理的784125卡

4870个完成

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值