【问题标题】:Why JVM calculated PS Survivor Space size too low for parallel collector为什么 JVM 计算的 PS Survivor Space 大小对于并行收集器来说太小了
【发布时间】:2016-07-26 01:28:50
【问题描述】:

我将JDK1.6.0_16 JVM 用于托管在Linux Intel procesor 80 cores machine 上的Java 应用程序。

在启动 Java 应用程序时,我只配置了两个选项 -Xms2048m -Xmx8000m 在 JVM 选项中(在 java 命令之后)。 我看到 PS Old Gen 计算为5.21G,PS Eden 计算为2.6G,但 PS Survivor 空间为25MB。

我在生产中使用完全相同的 JVM,并且 PS Survivor Space 大小显示为 888MB。我在 java 任务控制内存选项卡中看到这些大小。 缓存大小(/proc/cpuinfo 的输出)在 UAT 和生产框中均显示为 24656。

不要认为这对 JVM 有任何影响,但仍然提到在启动 JVM 时机器上的负载非常低。

能否请您告知 JVM 考虑哪些参数来计算 PS Survivor Space 大小?

【问题讨论】:

  • 还有一件事。这台机器有 256G 的物理内存,其中大约 200G 是空闲的(包括缓冲区和缓存,不包括交换)
  • 在设置 -XX:SurvivorRatio=1 后(设置其他值如 8、6、5 后),PS Survivor Space 大小刚刚增加到 220 MB。将值设置为 8 没有任何效果,然后设置为 6 仅更改边距。

标签: garbage-collection jvm heap-memory jvm-arguments parallel-collections


【解决方案1】:

您能否告知 JVM 在计算 PS Survivor Space 大小时考虑哪些参数?

它必须足够大,以至于在收集 Eden 空间后永远不会真正填满,否则您将获得不受欢迎的 Full GC。

什么是最佳 Survivor 空间大小取决于您的应用程序。我建议您在实际负载下测试您的应用程序,使用比您想象的更大的 Eden 和 Survivor 空间,看看该空间有多少被使用过,并根据您看到的使用情况增加 50% 到 100%。

这台机器有 256G 的物理内存,其中 ~200G

默认堆大小为 32 GB,我建议您使用此默认值,除非您有充分的理由减少它。

-XX:SurvivorRatio=1

这通常是个坏主意,拥有像 8 这样的高存活率通常更好。

将值设置为 8 没有任何效果

很可能您的分配率较低。我通常会设置一个较高的 Young 空间,例如 -Xmn8g 甚至 -Xmn24g,但这是否是一个好主意/坏主意取决于您的应用程序。

【讨论】:

  • @4999394 我无法测试,因为低生存空间大小导致幸存者一直是空的,而伊甸园总是满的。因此,由于 PS 幸存者空间低,物体直接从伊甸园移动到旧世代。所以我需要正确设置 PS Survivor Space。让我感到困惑的是,生产中的同一个 JVM 分配了更高的内存,即按照默认的 SurvivorRatio=8。在 UAT 环境中默认 SurvivorRatio 为 8,但 Eden 和 Survivor 的实际比例为 106 (2.6G*1024/25 MB)。我设置了各种 SurvivorRatios 以查看对 SurvivorSpace 的影响,但没有显着增加。
  • @NewMember 生产和 UAT 中的负载有多相似?
  • 生产环境中的 jvm 独立实例负载非常重,每个实例都有一些工作要做。在我上面的问题中,5 个实例具有堆内存分配。其他的最大堆大小为 2G-4G,但每个实例都有事情要做。 UAT 实例非常安静,只有 8 个 jvm 实例。
  • @NewMember 不同的是负载足以产生这样的差异。
  • @Ravindra 感谢您的关注和宝贵的帮助。我应用 -Xmn4g 和 -XX:SurvivorRatio=4 来实现 UAT 中的 Eden 和 Survivor 空间大小,并且能够接近与 Prod 相当的空间大小。不理想,但至少我可以测试。我将尝试增加 UAT 中的实例数量,并将观察并通知。谢谢。
【解决方案2】:

来自 oracle gc 调优article 1 和article 2:

幸存者空间大小

您可以使用参数SurvivorRatio 来调整幸存者空间的大小,但这通常对性能并不重要。例如,-XX:SurvivorRatio=6 将伊甸园和幸存者空间之间的比例设置为 1:6。

In other words, each survivor space will be one-sixth the size of eden, and thus one-eighth the size of the young generation (not one-seventh, because there are two survivor spaces).

如果幸存者空间太小,复制集合会直接溢出到终身代。如果幸存者空间太大,它们将是无用的空。

NewSize 和 MaxNewSize 参数控制新一代的最小和最大大小。通过将这些参数设置为相等来调节新生代的大小。 The bigger the younger generation, the less often minor collections occur.

NewRatio:新生代相对于老年代的大小由NewRatio控制。比如设置-XX:NewRatio=3,表示老年代和年轻代的比例是1:3,the combined size of eden and the survivor spaces will be fourth of the heap。

正如Peter Lawrey 正确引用的那样,设置幸存者取决于您的应用程序的类型。来自 Oracle 的 gc 调整文章,这里是指导方针。

  1. First decide the maximum heap size you can afford to give the virtual machine。然后将你的性能指标与年轻代的大小进行对比,以找到最佳设置

  2. If the total heap size is fixed, then increasing the young generation size requires reducing the tenured generation size。保持老年代足够大,以容纳应用程序在任何给定时间使用的所有实时数据,以及一些松弛空间(10% 到 20% 或更多)。

  3. 受限于之前对老年代的约束:为年轻代提供足够的内存和increase the young generation size as you increase the number of processors, because allocation can be parallelized。默认值是根据NewRatio 和-Xmx 设置计算得出的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-10
    • 2013-06-07
    • 2019-04-07
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多