问题标签 [g1gc]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
5750 浏览

java - 为什么 G1GC 在开始混合收集之前会收缩年轻代?

当 G1 决定需要开始混合收集时,它会积极地将我们的 Eden 空间从 10g 缩小到大约 1g。

这是在使用 10-11g 的 Eden 运行 60 个或更多集合之后。

以下是我们正在运行的适当 JVM GC 参数

根据本演示文稿的第 55 页,它需要调整 Eden 的大小,以便最大暂停目标占整个堆,而不仅仅是新一代。收藏家为何如此咄咄逼人?

对于 10g 的堆大小,平均年轻代暂停时间在 50-150ms 之间。如果演示文稿是正确的(我没有找到其他任何东西来支持该声明),我预计会缩小一半(20g 堆),而不是 10 倍。

0 投票
2 回答
5643 浏览

java - 如何调整 G1GC 以获得更小的内存占用?

我一直在我的一个项目中使用 Java 8 (Oracle JVM) 试验 G1GC。我的 GC 标志实际上是:

我观察到堆比我拥有的实时数据量大得多。GC 日志显示了我认为的根本原因:

实际上,我的应用程序正在生成大量垃圾,因此花费在 GC 上的时间比例高于 10%,因此 G1 的人体工程学增加了堆大小。


使用 Parallel 收集器可以调整此阈值-XX:GCTimeRatio(吞吐量目标),但从我在文档中看到的内容来看,G1 没有等效标志。

对于并行收集器,Java SE 提供了两个基于实现应用程序指定行为的垃圾收集调优参数:最大暂停时间目标和应用程序吞吐量目标;请参阅并行收集器部分。(这两个选项在其他收集器中不可用。)请注意,这些行为并不总是能够满足。

我的问题是,除了降低最大堆大小之外,我如何调整 G1GC 以获得更小的内存占用?

在日志中,没有证据表明我超出了最大暂停时间目标,并且确实增加了这一目标并不能解决问题。


这可能是这个问题的欺骗:哪个 JVM Flag 设置了 G1Ergonomics 日志中提到的 GC 开销阈值?,但似乎已接受了不正确的答案。(或者也许它只对旧版本的 JVM 是正确的。)

0 投票
2 回答
1899 浏览

java - 由于卡表验证失败,JVM Crash with G1 GC

最近我们开始使用 OpenJDK JRE 而不是 Oracle 的 JRE。环境包括:

  1. 雄猫 8.0.29
  2. CentOS 6.7 (2.6.32-279.el6.imp6.numa.x86_64 #1 SMP Wed Mar 30 11:50:42 IDT 2016 x86_64 x86_64 x86_64 GNU/Linux)
  3. Java 8 更新 71
  4. G1 垃圾收集算法

由于“Java 运行时环境检测到致命错误” ,服务器会定期崩溃。我向 java 社区 ( JDK-8144331 ) 报告了这件事,但他们以“通常我们不调查 OpenJDK 问题”的说法放弃了它。

我开始自己调查根本原因,我用调试的 RPM 替换了生产 RPM,并安装了 GDB 和 debuginfo 包。打印到 catalina.out 的下一个错误:

GDB 工具从核心转储中提取了下一个堆栈跟踪:

现在我很清楚,由于VM_G1IncCollectionPause期间卡表的验证失败而发生错误。我怀疑发生了一些内存损坏。

该问题在 Oracle 的 JRE 和默认 GC 上都无法重现。我们确实使用 JNI 调用。

问题:

  1. 建议使用其他工具来了解这种情况是如何发生的
  2. Oracle 和 OpenJDK 项目之间的 G1 实现是否不同?
  3. 为什么卡表验证如此重要?

更新1:

OpenJDK RPM 信息:

更新 2:

我设法在 Oracle 的 JRE 版本 8 更新 77 下重现了崩溃,但错误发生在不同的方法:

崩溃错误 1:

崩溃错误 2:

该问题已报告给 Oracle 团队。

0 投票
1 回答
4158 浏览

java - Java 8 中使用 G1 垃圾收集器的不必要的 Full GC?

我们注意到偶尔会出现带有并发标记溢出的 G1 垃圾收集器的完整 GC。一旦出现并发标记重置溢出,此溢出将在下一个并发标记阶段继续。最终,它会导致完整的 GC,因为并发标记似乎不再起作用。

我们有四台机器运行相同的基于 Apache Storm 的应用程序,具有相同的数据流量。每周只有一台机器有这种体验。

这是否与错误有关:'G1 在并发标记期间发生标记堆栈溢出时不会扩展标记堆栈' https://bugs.openjdk.java.net/browse/JDK-806540​​2

根据上一页的建议,我们将并发标记线程从 4 个增加到 8 个,堆大小从 8GB 增加到 16GB。但是,完整的 GC 仍然会发生,唯一的区别是发生延迟。

还有其他建议吗?

这是GC日志:

0 投票
1 回答
9719 浏览

java - 为什么在达到 InitiatingHeapOccupancyPercent 时 G1 不开始标记周期?

根据文件XX:InitiatingHeapOccupancyPercent

设置触发标记周期的 Java 堆占用阈值。默认占用率为整个 Java 堆的 45%。

在我目前的环境中,这不会发生。

我的G1垃圾回收配置如下

对于 25g 堆和XX:InitiatingHeapOccupancyPercent70% 的堆,您会期望在 18g 被占用时开始一个标记周期。我正在跟踪垃圾收集日志,但这并没有发生。

这是一个摘录:

我会提请你注意

超过 70% 的堆在此收集之前被占用。为什么这没有触发标记周期?

应用程序继续进行年轻代收集,填满旧区域,最终导致分配失败和冗长的 Full GC。


减少InitiatingHeapOccupancyPercent到 55 没有明显的效果。

在 20 岁时,它确实开始进行混合收集,但仅在大约 80% 的堆被占用时。

0 投票
0 回答
1193 浏览

logstash - 如何配置 logstash 来解析 G1GC loggc 文件

在我们的生产环境中,我们有一个 ELK 堆栈,用于监控我们自己的日志文件。

我们还启用了 g1-gc 日志记录:

但是,我们还没有分析这些日志文件。我们有兴趣让 logstash 处理这些文件,以便我们可以开始使用它们。

是否有任何适用于 G1GC 日志文件的示例 logstash 输入配置?

谢谢

0 投票
1 回答
617 浏览

java - G1GC 不常见的长时间 GC 暂停

我在使用 G1GC 算法时遇到了罕见的长时间 GC 暂停 - 一个月超过 30 秒。一旦发生,我将重新启动我的服务,并且在接下来的 1 个月内不会再次发生这种延迟。

我正在附加 GC 日志。

我正在使用以下 G1GC 标志:

机器配置:

我们如何从上面的陈述中找到导致长时间 GC 的根本原因?

0 投票
1 回答
1801 浏览

spring-boot - JVM空闲时释放内存给操作系统

我们有一个简单的微服务设置,基于 Windows 服务器上的 Spring Boot 和 Java 8。

许多服务的负载都很低,因为它们作为各种外部合作伙伴的集成。所以他们很多时候都是闲着的。

问题是 JVM 仅在触发垃圾收集时才将内存释放回操作系统。因此服务可能开始使用 32mb,然后服务单个请求并分配 2GB 内存。如果该服务上没有其他活动,则不会进行 GC,服务器上的其他服务将受到影响。

使用 System.gc 在外部或内部触发 GC 工作得很好,我已经弄清楚如何使用和-XX:MaxHeapFreeRatio控制堆何时应该扩展并向操作系统释放内存。-XX:MinHeapFreeRatio-XX:+UseG1GC

我的问题是:当 JVM 空闲时,确保内存重新回到操作系统的最佳方法是什么?

一个想法是让服务监控自己并在一段空闲时间后触发 System.gc,但这可能很棘手且容易出错。所以希望有更好的建议。

您可以通过运行该程序的 X 个实例来重现。大约 10 个让我的 8GB Windows 机器放弃了。

c:\> java -server -XX:+UseG1GC -Xms32m -Xmx2048m Load

编辑:这被标记为重复两次,但它不是链接问题的重复。第一个问题是同一个问题的 2010 版本,但这个问题是关于为什么 GC 不将内存释放回操作系统(当时不可能)。另一个问题是关于基本 GC 设置的,我已经写过我理解的。我希望讨论如何在系统空闲时触发垃圾收集器。因此,每五秒运行一次 System.gc 是不可接受的,因为那样会与有效请求发生冲突并破坏响应时间的风险很高。

0 投票
1 回答
625 浏览

java - G1 收集器没有进行完整的 GC

切换到 java 1.7.0_80 一周后,观察到这种行为

S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT 0 32M 0 32M 512M 128M 9.5G 7.7G 640M 475M 26487 157min 0 0min 157min

没有 Full GC,分配给老年代的大空间和年轻代发生的收集太多。

通过 JMX 调用完整 GC 后

S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT 0 32M 0 32M 5.2G 768M 4.8G 2.7G 640M 475M 26592 158.4min 1 0.1min 158min

而且GC时间减少了很多。

参数是

可能是因为 -XX:MaxGCPauseMillis=100?

老一代中的很多对象都保存在 ehcache 中,TimeToIdle 为 10 分钟,但如果在过期后没有请求相同的对象或缓存未满,ehcache 不会清理对象。

0 投票
1 回答
1317 浏览

java - G1 和 CMS 的 UseCompressedOops 启动阈值不同

我正在运行 Oracle 的 64 位 Java 1.8 Hotspot JVM。当使用不同的 GC 机制时,我一直试图围绕 JVM 的行为差异来启动压缩对象指针。例如:

我已尝试更改其他一些 G1GC 旋钮,但无法获得压缩指针优化以启动 G1 超过 32736 MB 的堆大小。但是,您可以清楚地看到,CMS 可以将压缩指针用于高达 32766 MB 的堆大小。我试图了解是什么控制了不同 GC 算法的这个阈值。