5

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

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

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

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

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

4

1 回答 1

5

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

Haswell i7(4 核/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 秒的暂停时间。

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

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

  • 寻呼
  • 热 CPU 节流
  • 由非常大的、大量引用的对象组成的工作负载
  • NUMA 配置中的非本地内存流量
  • 其他进程争夺 CPU 时间
  • 大量使用弱/软引用

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

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

我说没有交互是正确的,但我仍然有严格的许可协议。我需要在一小时内完成整个处理过程。所以我无法承受30分钟的世界盛会。

基本上,您并不需要 CMS、G1、Shenandoah 或 Zing 所针对的低暂停时间(即使在大堆上,它们的目标也是 <100ms 甚至 <10ms)。

您所需要的只是 STW 暂停不会造成灾难性的严重影响,以至于它们会占用您很大一部分计算时间。

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

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

于 2016-07-10T11:19:50.500 回答