在非交互式应用程序中处理 150GB 堆

Dealing with 150GB heap in non interactive application

您好,我有一个使用 In Memory Data 网格的 150GB 堆内存程序的案例。我有一些来自运营部门的疯狂要求,要求使用一台机器。现在我们都知道如果使用超过 150GB 的并行垃圾收集器会发生什么,如果调用 FULL GC 可能需要数十分钟的垃圾收集。

我希望 Java 9 即将到来的 Shenandoah 低暂停 GC。不幸的是,据我所知,它没有在 Java 9 中列出。有人知道吗?

尽管如此,我想知道 G1 GC 将如何处理这个堆内存量。

还有最后一个问题。因为我有非交互式批处理应用程序,应该在 2 小时内完成,所以可以这么说。这里的主要目标是确保 Full GC 永远不会启动。如果我确保有足够的内存让我们说如果可以达到的最大堆是 150 并且我分配它 250GB 我可以很有信心地说 Full GC 永远不会启动或者?通常新生代+老年代触及最大堆就会触发full GC。可以用不同的方式触发吗?

有一个重复的请求我会尝试在这里解释为什么这个问题不是重复的。首先,我们谈论的是 150GB 堆,这给问题增加了完全不同的维度。其次,我没有像提到的问题那样使用 RMI,第三,我在 lines.Also 之间询问有关 G1 垃圾收集器的问题,一旦我们超过 32GB 堆屏障,我们将进入 64 位地址 space你不能说服我关于 <32GB 堆的问题与堆 >32GB 的问题相同 更不用说自 Java 7 以来事情发生了一些变化,例如 PermSpace 不存在。

压缩 GC 的经验法则是每个核心每秒应该能够处理 1 GB 活动对象

使用并行收集器的 Haswell i7(4 cores/8 线程)和 20GB 堆上的示例:

[24.757s][info][gc,heap        ] GC(109) PSYoungGen: 129280K->0K(917504K)
[24.757s][info][gc,heap        ] GC(109) ParOldGen: 19471666K->7812244K(19922944K)
[24.757s][info][gc             ] GC(109) Pause Full (Ergonomics) 19141M->7629M(20352M) (23.791s, 24.757s) 966.174ms
[24.757s][info][gc,cpu         ] GC(109) User=6.41s Sys=0.02s Real=0.97s

压缩后的live set是7.6GB。它需要 6.4 秒的 cpu 时间,由于并行性,这转化为 <1 秒的暂停时间。

原则上,并行收集器应该能够在多核系统上以 < ~2 分钟的完整 GC 时间处理 150GB 的堆,即使大部分堆由活动对象组成。

当然这只是一个经验法则。一些可能对其产生负面影响的事情:

  • 分页
  • 热 CPU 节流
  • 由非常大的引用大量对象组成的工作负载
  • NUMA 配置中的非本地内存流量
  • 其他进程竞争 CPU 时间
  • 大量使用 weak/soft 参考资料

在某些情况下,可能需要调整才能实现此吞吐量。

如果并行收集器无法正常工作,那么 CMS 和 G1 可能是可行的替代方案,但前提是有足够的备用堆容量和 CPU 个内核可用于 JVM。他们需要大量的喘息空间来完成并发工作,而不必冒完全 GC 的风险。

It is correct I said no interactive, but still I have a strict license agreements. I need to be finished with the whole processing in an hour. So I can no afford 30 minutes stop the world event.

基本上,您并不真正需要 CMS、G1、Shenandoah 或 Zing 所追求的那种低暂停时间(它们的目标是 <100 毫秒,甚至在大型堆上也是 <10 毫秒)。

您所需要的只是 STW 暂停不会严重到占用您计算时间的很大一部分。

这对于大多数可用的收集器来说应该是可行的,忽略串行收集器。

在实践中,存在一些病态的边缘情况,它们可能会失败,但要达到这一点,您需要根据实际工作负载设置系统并进行一些测试运行。如果您遇到一些实际问题,那么您可以提出更详细的问题。