【问题标题】:64Bit Java 8 on Windows Server 2008 uses more or less whole server CPUWindows Server 2008 上的 64 位 Java 8 使用或多或少的整个服务器 CPU
【发布时间】:2016-09-26 09:39:25
【问题描述】:

在从 32 位(oracle 8u33)迁移到 64 位(oracle 8u66 也是 102)期间,我们遇到过这样的情况,即单个 java 进程使用机器的所有 16 个内核,或者在启动后 5-15 分钟的持续时间超过 50%。我们的日志表明有大量 I/O 的时期(即通过休眠写入 MySQL)由于在较长时期内的糟糕性能而被延长。一旦输出写入频率下降,cpu 就会回到已知的低值。

我们以前从未见过如此极端的 CPU 使用率。我们的应用程序是 I/O,而不是 CPU 资源密集型。它通常需要远远少于一个内核。我们已经在 Windows 服务器上运行了大约 6 年。

我的假设是,当堆变得紧张时(与 64 位版本相同的 xml 设置),jvm 会尝试不惜一切代价避免“堆外”情况:

  • 当堆使用量达到低于配置的最大大小约 70MB 的“上限”时,visual vm 显示高 cpu(主要不是与 GC 相关的 CPU!)。
  • 确实,在增加堆大小后 -> 高 cpu 症状消失了。

虽然我知道解决方法,但我在此处输入的目标是两件事:

  • 有人可以证实这个假设吗?
  • 详细了解 jvm 在做什么以及为什么 - 它是 v8/64Bit/windows 特定的吗?
  • 如何调整 jvm 行为以不影响其他进程(我们在服务器上有 >50 个实例),而是放弃、用完内存并死掉(我们有可用性监控并可以跟进)?

提前致谢

【问题讨论】:

  • 听起来你实际上是内存受限,而且你的堆限制对于你的工作集来说太低了。
  • 如果您不增加堆大小,尤其是如果您已经接近限制,则可能会发生这种情况。如果您想最小化开销,我建议您将工作大小设置为最大 3 倍。也许由于您的机器很旧,您的内存使用量有限。注意:如今,典型的服务器是 32 GB - 128 GB 内存,通常不会留出几 GB 的空间。
  • 在我看来,这些是几个不相关的问题。一是关于如何解决one JVM的资源耗尽问题,二是如何协调一台机器上多个JVM的资源消耗。你应该单独问他们。
  • @Peter:我们已经有很多内存和增加了部分实例的堆。
  • @the8472 回答了原始问题,因为似乎没有人认为 CPU 行为不正常。然后另一个问题,如何使 jvm 默认设置“不那么自私”现在似乎很明显:调整 GC 以仅使用一次 core max(并查看)。如果没有 pb,我们可以承受几秒钟的暂停。幸运的我们:)

标签: java oracle jvm 64-bit heap-memory


【解决方案1】:

当 64 位 jvm 内存不足时,我们看到的情况是“正常的”。 默认情况下,它会非常积极地运行具有如此多并行线程的 GC,以至于整个服务器都会受到影响。

由于我们有许多 jvm 正在运行,我们不希望在其中一个内存不足时对所有其他 jvm 产生影响。解决方案是使用单线程 gc:-XX:+UseSerialGC(以及限制元空间-XX:MaxMetaspaceSize=512m)。从那时起 - 大约一年前 - jvms 表现良好。 jvm 的默认设置似乎已针对单独在服务器上进行了调整

【讨论】:

    【解决方案2】:

    (与 64 位版本相同的 xmlx 设置)

    jvm 在 64 位上使用的内部结构将比 32 位消耗更多的内存(结构对齐和指针大小,如果没有别的) - 保持相同的最大堆大小 (-Xmx) 会带来麻烦。

    经过一番挖掘:

    • some reported“64 位需要 30-50% 的堆”以及“更长的垃圾收集暂停时间”。

    • 对于 java5 很抱歉 Oracle 的常见问题解答 mentions 需要从过大的值中调低 -Xmx 并使用 -Xincgc 以避免那些较长的 CG 时间罢工>

    • Java 8 GC tuning here

    【讨论】:

    • 我查看了 java GC 调整链接。它描述了宁愿消耗 CPU 而不是允许更长的暂停的范例。同样从阅读它让我觉得在内存不足的情况发生之前开销必须很大。 Jconsole 显示使用了 PS Mark Sweep GC。它没有解释为什么比典型的四分之一核心更忙(这里是整个盒子)。对我来说,感觉好像 (sys?) 调用会消耗大量 cpu,而不是 GC 本身,至少 visualvm 中的图表暗示了这一点。我现在设置 -XX:+UseSerialGC 并减少堆并且会看到。
    • 您的回答包含错误信息。 a) 内部 JVM 结构不是 java 对象堆的一部分 b) 在最大堆大小
    • @the8472 使用模因...[需要引用] 我很高兴能够得到纠正,但如果要进行更正,请以与我相同的方式提供来源。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 2017-10-21
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多