Java GC1 不会抛出 OutOfMemory 但一直在挣扎

问题描述

我希望我的应用程序在内存不足的情况下快速失败,因此可以对其进行调整并重新启动进程。 我正在运行服务

-XX:ParallelGCThreads=8

-XX:GCTimeRatio=19

-XX:ConcGCThreads=2

当堆内存耗尽时,GC1 会继续执行 Full Garbage Sweeps,即 STW(停止世界)事件。它勇敢地战斗,但徒劳无功。 jstat -gnew 显示连续 10 次 FGC 尝试未能确保超过 0.03% 的 Olg Den 空间

我查看了 GC1 文档,但我找不到合适的选项来指示 GC1 在无法回收超过 0.05% 时抛出 OutOfMemory,比如 5 次 FGC 尝试。 有任何想法吗? 谢谢

解决方法

不能为何时应该抛出 OutOfMemoryException 配置任何阈值。

不幸的是,在 JVM 最终抛出 OutOfMemoryException 之前内存不足时,垃圾收集恐慌和长时间停止世界暂停是典型的。

在我对 G1GC 的优化中,已证明选项 -XX:+UseStringDeduplication 非常有价值。 效果取决于应用程序创建的字符串数量,例如由编组和解组引起的。

采用区域大小 (-XX:G1HeapRegionSize) 也有助于减少长时间 GC 中断的次数。特别是如果 GC 日志在 stop-the-world 事件之前频繁显示“to-space Exhausted”,则值得调整此选项。

根据我的经验,对于不那么烦人的长时间 GC 暂停的最佳优化是:

  • 向 JVM 添加更多 RAM ;-)
  • 应用程序的内存消耗更少(进行分析会话以查看内存消耗热点)
  • 尝试使用其他垃圾收集器(Shenandoah、Z1)更新的 Java 版本。
  • 当然还有检测应用程序中的内存泄漏

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...