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

时间:2016-07-09 20:15:11

标签: java performance garbage-collection jvm java-9

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

我的希望是Java 9将会出现Shenandoah低暂停GC。不幸的是,从我看来它没有列在Java 9中交付。有没有人知道这件事?

从未如此,我想知道G1 GC将如何为这一数量的堆内存执行。

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

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

1 个答案:

答案 0 :(得分:4)

压缩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

压缩后的实时设置为7.6GB。它需要6.4秒的CPU时间,由于并行性,这转换为<1s暂停时间。

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

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

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

在某些情况下,可能需要进行调整才能达到此吞吐量。

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

  

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

基本上,从CMS,G1,Shenandoah或Zing的目标来看,你真的不需要很短的暂停时间(他们的目标是<100ms甚至<10ms甚至大堆)。

你所需要的只是STW停顿不是那么灾难性的,它们会占用你计算时间的很大一部分。

这对大多数可用的收集器都是可行的,忽略了序列收集器。

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