问题描述
我希望我的应用程序在内存不足的情况下快速失败,因此可以对其进行调整并重新启动进程。 我正在运行服务
-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 版本。
- 当然还有检测应用程序中的内存泄漏