【问题标题】:Can I make the heap too big?我可以让堆太大吗?
【发布时间】:2014-10-01 06:56:21
【问题描述】:

我知道larger heap means longer GC pauses。我对此没意见——我的代码正在分析一些数据,我所关心的只是最大限度地减少垃圾收集所花费的时间,单次暂停的长度对我没有影响。

堆太大会影响性能吗?我的理解是“年轻”对象会很快被 GC,但“旧”对象可能需要更长的时间,所以我担心大堆会将一些寿命短的对象推入寿命更长的空间。我分配了很多很快被丢弃的字符串(在一次运行过程中大约 60 GB),所以我不想增加花费在这些上的 GC 时间。

我正在一台具有 8 GB RAM 的机器上进行测试,因此我一直在使用 -Xms4g -Xmx4g 运行我的代码,截至我上次分析运行时,我将大约 20% 的运行时间用于垃圾收集。我发现将堆增加到 5 GB 有助于减少它。生产服务器将具有 32 GB 的 RAM,以及更高的内存要求。

我可以使用-Xms31g -Xmx31g 安全地运行它,否则最终会影响性能吗?

【问题讨论】:

  • 我建议运行基准测试。
  • 您可以将-Xm* 标志置于的最高值是可用系统内存的一半,所以“否”...
  • @Makoto 这是真的吗?我已经在我的机器上设置了-Xm*5g(8 GB 内存)没有问题——你能提供一个来源吗?
  • 从什么时候开始限制可用系统内存的一半?我不记得有问题。然而,这个问题更多的是关于高级 GC 调优,它涉及的远不止-Xms-Xmx

标签: java memory garbage-collection jvm


【解决方案1】:

堆太大会影响性能吗?

当您超过 31 GB 时,您可能会丢失 CompressedOops,这意味着您必须跳到 48 GB 才能获得更多可用内存。如果可以的话,我会尽量保持在 31 GB 以下。

我的理解是“年轻”对象很快就会被 GC,但“老”对象可能需要更长的时间,所以我担心大堆会将一些寿命短的对象推入寿命更长的空间。

因此,我倾向于拥有大量的年轻一代,例如高达 24 GB。

我可以使用 -Xms31g -Xmx31g 安全地运行它,否则最终会损害性能吗?

在 32 GB 的机器上,这将是非常糟糕的。当您包括 JVM 使用的堆外、操作系统、磁盘缓存时,您可能会发现超过 24-28 GB 的堆会损害性能。我会从 24 GB 开始,看看情况如何,你可能会发现如果现在 5 GB 运行正常,你可以减少它,效果不大。

您可能会发现将数据移出堆会有助于 GC 时间。我运行的系统具有 1 GB 堆和 800 GB 堆外,但这取决于您的应用程序要求。

我将大约 20% 的运行时间用于垃圾收集

我建议您降低分配率。使用内存分析器,您可以将分配速率降低到 300 MB/s 以下,但小于 30 MB/s 更好。对于极端系统,您可能需要少于 1 GB/小时,因为这将允许您运行一整天而无需进行少量收集。

【讨论】:

  • 您建议将 24 GB 作为固定上限,还是将其引用为机器总内存的百分比?
  • @PatrickCollins 我敢打赌他的意思是你应该留出 4-8 GB 的空间用于其他用途(上面列出的),否则你会冒着交换的风险,这比你获得的成本要高得多大一点的堆。所以它既不是绝对上限也不是相对上限。
  • @maaartinus 好吧,我称之为相对的——相对于我正在使用的可用内存——而不是源于 JVM 的限制,事实上它正好是 24 GB这就是担心。我现在正在一台 60 GB 的机器上进行测试,看起来即使 48 GB 也不足以削减它。我理解与交换文件发生冲突的危险。
  • @PatrickCollins 是的,这就是为什么我开始说On a 32 GB machine ...
  • @PatrickCollins 这比你想象的更糟糕,如果你的堆开始交换程序将变得不可用,系统可能会变得不可用,在 Windows 上这可能意味着必须重启盒子,因为你可以'甚至不杀死进程。
猜你喜欢
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
相关资源
最近更新 更多