java - -XX:G1ReservePercent 和空间耗尽
问题描述
我试图了解-XX:G1ReservePercent
实际做了什么。我在官方文档中找到的描述并不是很全面:
设置保留内存的百分比以保持空闲,以降低 to-space 溢出的风险。默认值为 10%。当您增加或减少百分比时,请确保将总 Java 堆调整相同的数量。
并且对空间耗尽日志条目的描述是这样的:
当您在日志中看到空间溢出/耗尽消息时,G1 GC 没有足够的内存用于幸存者或提升对象,或两者兼而有之。
[...]
要缓解此问题,请尝试以下调整:
增加
-XX:G1ReservePercent
选项的值(以及相应的总堆)以增加“to-space”的保留内存量。[...]
从引用来看,这to-space exhausted
意味着在执行混合疏散时,我们没有足够的自由区域来转移幸存者。
但这与以下在 Full GC 情况下的官方调整建议相矛盾(强调我的):
强制 G1 提前开始标记。G1 根据早期的应用程序行为自动确定启动堆占用百分比 (IHOP) 阈值。如果应用程序行为发生变化,这些预测可能是错误的。有两个选项:通过修改 增加自适应 IHOP 计算中使用的缓冲区来降低何时开始空间回收的目标占用率
-XX:G1ReservePercent
;
那么缓冲区是什么,设置有什么作用-XX:G1ReservePercent
(乍一看 AdaptiveIHOP 与它无关......)?
它是否总是保留一些堆空间,所以当混合疏散发生时,我们总是有空闲区域可以将幸存者移动到?
还是空间用于 G1 内部管家任务?如果是这样,则不清楚目标空间包含哪些数据以致耗尽?
解决方案
对我来说,理解它的真正作用,意味着去源代码。我选择了jdk-15
。
这个标志的最佳描述在这里:
它决定了我们应该在堆中拥有的最小储备,以最小化提升失败的概率。
太好了,所以这与“促销失败”(无论是什么)有关。但是根据你的粗体字,这也有关系AdaptiveIHOP
吗?是的,这个参数只在 AdaptiveIHOP 中重要(默认情况下是打开的)。
另外需要注意的是,不能保证一直维护G1ReservePercentage
,这是尽力而为。
如果你看看它在下一行是如何使用的:
if (_free_regions_at_end_of_collection > _reserve_regions) {
absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
}
事情开始变得有意义(对于那个大胆的声明)。请注意如何提取_reserve_regions
某些计算。将为“促销失败”保留该空间(我们将解决这个问题)。G1
如果G1
保留该空间,则意味着可用于实际分配的空间更少。因此,如果您“增加此缓冲区”(G1ReservePercent
正如报价所建议的那样变大),则新对象的空间会变小,因此GC
需要启动的时间会更快,因此需要进行空间回收的时间将也快来(“降低何时开始空间回收的目标占用率......”)。这是一个复杂的句子,但用简单的话来说,它意味着:
如果增加
G1ReservePercentage
,则需要更快地回收空间(更频繁的 GC 调用)。
公平地说,这是显而易见的。并不是说我同意您应该增加该值,但这就是那句话的意思。
在某个 GC 周期之后,be that或 ,知道minor
有多少个区域是空闲的:mixed
major
G1
_free_regions_at_end_of_collection = _g1h->num_free_regions();
当然,哪个是“空闲列表”的长度:
return _free_list.length();
基于这个值和_reserve_regions
( G1ReservePercent
) 加上目标暂停时间(200 ms
默认情况下),它可以计算下一个周期需要多少个区域。到下一个周期结束时,可能会出现没有空区域的情况(或者空的区域无法获取所有应该移动的活动对象)。应该在哪里Eden
移动活动对象(Survivor
),或者,如果old region
是碎片化的 -应该将活动对象移动到哪里进行碎片整理?这就是这个缓冲区的用途。
它充当安全网(代码中的注释使这更容易理解)。这是需要的,希望它能避免Full GC
. 因为如果没有空闲区域(或足够多的区域)来移动活动对象,则需要发生 Full GC(很可能后面跟着young GC
也)。
当这条消息出现在日志中时,这个值通常被认为很小。要么增加它,要么更好地为应用程序提供更多堆。
推荐阅读
- javascript - AJAX 脚本在移动设备中使用时不起作用
- python - 键入提示@asynccontextmanager 的返回值的正确方法是什么?
- matplotlib - Matplotlib 带月 X 轴的线图
- javascript - 我如何实现分页和搜索以适应将数据传递到服务器端
- python - 如何将十六进制字符串转换为字节?
- html - 如何将带有
标签的段落格式化为合理的? - java - .jar 文件(使用 Batik 依赖项)仅适用于特定文件夹
- powershell - 如何将来自 PowerShell 的 API 与 OAUTH 2.0 连接起来?
- python - model.predict 返回值
- ruby-on-rails - 如何使用主域的证书文件运行 2 个 rails 项目?