我试图了解-XX:G1ReservePercent
的实际作用。我在official documentation中找到的描述并不是很全面:
设置保留内存的百分比以保持空闲,以减少 太空溢出的风险。默认值为10%。当你 增加或减少百分比,请确保调整总计 Java堆的数量相同。
对空间耗尽的日志条目的描述是这样的:
当您在日志中看到空间上的溢出/耗尽消息时,G1 GC没有足够的内存供生存或升级 对象,或两者皆有。
[...]
要缓解此问题,请尝试以下调整:
增加
-XX:G1ReservePercent
选项的值(以及总计 相应地进行堆)以增加“至空间”的保留内存量。[...]
用引号to-space exhausted
来判断,这意味着在执行混合后送时,我们没有足够的自由区域将幸存者转移到那里。
但这与以下official tuning advice in case of Full GC(强调我的)相矛盾:
强制G1更早开始标记。 G1自动确定 根据早期情况启动堆占用百分比(IHOP)阈值 应用程序行为。如果应用程序行为发生变化,这些 预测可能是错误的。有两个选项:降低目标 通过增加缓冲区来开始空间回收的时间 通过修改用于自适应IHOP计算
-XX:G1ReservePercent
;
那么缓冲区是什么,设置-XX:G1ReservePercent
的作用是什么(乍一看AdaptiveIHOP与它无关...)?
它是否始终保留一些堆空间,所以当混合疏散发生时,我们总是有自由的区域将幸存者移到那里?
还是该空间用于G1内部内部整理任务?如果是这样,则尚不清楚目标空间包含哪些数据,因此将其用尽?
答案 0 :(得分:2)
对我来说,了解其真正的功能意味着可以使用源代码。我选择了jdk-15
。
此标志的最佳描述是here:
它确定了我们在堆中应具有的最低保留量,以最大程度地降低升级失败的可能性。
非常好,所以这与“促销失败”(无论是什么)有关。但是根据您用粗体引用的话,这是否与AdaptiveIHOP
有关? yes, this parameter matters only in AdaptiveIHOP(默认情况下处于启用状态)。
要注意的另一件事是G1ReservePercentage
有no guarantee to be maintained all the time,这是尽力而为。
如果在下一行中查看它的用法,则:
if (_free_regions_at_end_of_collection > _reserve_regions) {
absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
}
事情开始变得有意义(对于那个大胆的陈述)。注意如何_reserve_regions
进行提取以进行一些计算。 G1
将保留用于“促销失败”的空间(我们将会做到这一点)。
如果G1
保留了该空间,则意味着 less 空间可用于实际分配。因此,如果“增加此缓冲区”(使G1ReservePercent
增大,如报价所示),则用于新对象的空间将变小 ,因此GC
需要将会很快出现,因此需要进行空间回收的时间也会很快出现。(“降低何时开始空间回收的目标占用率... ”)。这是一个复杂的句子,但简单地说就是:
如果您增加
G1ReservePercentage
,则需要更快地回收空间(更多的是GC调用)。
公平地说,这是显而易见的。并非我同意您应该增值,但这就是那句话的意思。
在某个GC周期后,应为minor
,mixed
或major
,G1
knows how many regions are free:
_free_regions_at_end_of_collection = _g1h->num_free_regions();
当然是"free list"的长度:
return _free_list.length();
基于此值和_reserve_regions
(G1ReservePercent
)加上目标暂停时间(默认为200 ms
),它可以计算下一个周期需要多少个区域。到下一个周期结束时,可能会出现没有空区域的情况(或者,那些空区域无法获取所有应移动的活动对象)。 Eden
应该在哪里移动 live 对象(Survivor
),或者,如果old region
是零散的, live 对象应该在哪里移到碎片整理?这就是此缓冲区的用途。
它起着safety-net的作用(代码中的注释使此内容更易于理解)。希望这样做可以避免使用Full GC
。因为如果没有空闲区域(或没有足够的空间)来移动活动对象,则需要发生Full GC(很有可能还会出现young GC
)。
通常在this message is present in logs时此值较小。要么增加它,要么更好地给应用程序增加更多的堆。