【问题标题】:Why is the 64bit JVM faster than the 32bit one?为什么 64 位 JVM 比 32 位更快?
【发布时间】:2011-02-08 09:19:22
【问题描述】:

最近我一直在对我公司的数据库产品的写入性能进行一些基准测试,我发现简单地切换到 64 位 JVM 可以持续提高 20-30% 的性能。

我不能详细介绍我们的产品,但基本上它是一个面向列的数据库,针对存储日志进行了优化。基准测试包括为其提供几 GB 的原始日志,并计时分析它们并将它们作为结构化数据存储在数据库中所需的时间。 CPU 和 I/O 的处理都非常繁重,虽然很难说比例是多少。

关于设置的几点说明:

Processor: Xeon E5640 2.66GHz (4 core) x 2
RAM: 24GB
Disk: 7200rpm, no RAID
OS: RHEL 6 64bit
Filesystem: Ext4
JVMs: 1.6.0_21 (32bit), 1.6.0_23 (64bit)
Max heap size (-Xmx): 512 MB (for both 32bit and 64bit JVMs)

两个 JVM 的常量:

  • 相同的操作系统(64 位 RHEL)
  • 相同的硬件(64 位 CPU)
  • 最大堆大小固定为 512 MB(因此速度提升不是由于 64 位 JVM 使用更大的堆)

为简单起见,我已关闭产品中的所有多线程选项,因此几乎所有处理都以单线程方式进行。 (当我开启多线程时,系统当然更快了,但 32 位和 64 位的性能比保持不变。)

所以,我的问题是……为什么在使用 64 位 JVM 时我会看到 20-30% 的速度提升?以前有人见过类似的结果吗?

到目前为止,我的直觉如下:

  • 64bit 指针更大,L1 和 L2 缓存更容易溢出,因此在 64bit JVM 上性能更差。

  • JVM 使用了一些花哨的指针压缩技巧来尽可能地缓解上述问题。 Sun 网站here 上的详细信息。

  • 在 64 位模式下运行时,允许 JVM 使用更多寄存器,这会稍微加快速度。

鉴于以上三点,我预计 64 位的性能会稍慢,或大约等于 32 位的 JVM。

有什么想法吗?提前致谢。

编辑:阐明了有关基准环境的一些要点。

【问题讨论】:

  • 您是否在 64 位操作系统上运行您的 32 位 JVM?如果是,那么您必须记住,64 位操作系统上的 32 位应用程序将被“模拟”,因此它会失去一些性能。检查 32 位操作系统 -> 32 位 JVM 和 64 位操作系统 -> 64 位 JVM 的性能
  • 另外,这可能与内存有关吗?也就是说,在您能够访问更多内存的 64 位版本上,是不是因为资源没有那么紧张,所以 GC 不需要运行那么多或那么激进?
  • 是的,请确保使用相同的内存设置运行基准测试。
  • 对不起,我应该提到两个 JVM 都运行在相同的 64 位操作系统和 CPU 上,具有相同的堆大小。我已经编辑了问题以澄清这些观点。
  • 如果你使用 -XX:+UseCompressedOops 运行会怎样

标签: java 64-bit jvm performance


【解决方案1】:

发件人:http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#64bit_performance

“通常,与在 32 位 VM 上运行相同的应用程序相比,能够处理大量内存的好处是在 64 位 VM 中性能损失较小。这是因为每个本机指针在系统中占用 8 个字节而不是 4 个。加载这些额外数据会对内存使用产生影响,这会导致执行速度稍慢,具体取决于在 Java 程序执行期间加载了多少指针。好消息是AMD64 和 EM64T 平台在 64 位模式下运行,Java VM 获得了一些额外的寄存器,可用于生成更有效的本机指令序列。这些额外的寄存器将性能提高到与 32 相比通常根本没有性能损失的程度到 64 位执行速度。
当您迁移到 64 位 VM 时,比较在 64 位平台上运行的应用程序与在 SPARC 上运行 32 位平台的应用程序的性能差异大约为 10-20%。在 AMD64 和 EM64T 平台上,此差异范围为 0-15%,具体取决于访问应用程序执行的指针数量。”

【讨论】:

    【解决方案2】:

    在不了解您的硬件的情况下,我只是在进行一些疯狂的尝试

    • 您的特定 CPU 可能正在使用微码来“模拟”某些 x86 指令,尤其是 x87 ISA
    • x64 使用 sse 数学而不是 x87 数学,在这种情况下,我注意到一些数学密集型 C++ 应用程序的速度提高了 %10-%20。如果您使用strictfp,数学差异可能是真正的杀手。
    • 内存。 64 位为您提供更多的地址空间。可能 GC 在 64 位模式下没有那么激进,因为您有额外的 RAM。
    • 您的操作系统是否处于 64b 模式并通过一些包装实用程序运行 32b jvm?

    【讨论】:

    • 两个 JVM 的堆大小都固定为 512m,所以我不认为内存/GC 问题在这里起作用。但是您关于 32 位/x86 仿真和不同数学指令集的观点听起来很合理。感谢您的想法。
    • @Chris 我看到你选择了我的答案。愿意分享它最终是哪一点?
    • 说实话,我还不确定。作为一个数据库,应用程序并不是真正的数学繁重(特别是很少的浮点计算),所以我认为 32 位 JVM 的减速很可能是由于仿真造成的。正如您所建议的,此仿真将在操作系统端以“32 位模式”运行 JVM,或者在 CPU 端以微码模拟 x86 指令。目前我们没有可用于在同等硬件和 32 位操作系统和/或 CPU 上尝试基准测试的硬件,因此我无法确认这一点。
    • Emulation 从我对该主题的研究中获得了我的投票。
    【解决方案3】:

    64 位指令集多了 8 个寄存器,这应该会使代码整体更快。

    但是,由于当今的处理器主要等待内存或磁盘,我想内存子系统或磁盘 i/o 在 64 位模式下可能更有效。

    【讨论】:

      【解决方案4】:

      我的最佳猜测是基于 32 位和 64 位性能图表的快速 google, 是 64 位 I/O 效率更高。我想你做了很多 I/O...

      如果在移动数据时涉及 memcpy,复制 long 可能比 int 更有效。

      【讨论】:

      • 这很有趣,我从未听说过 64 位 I/O 效率更高,尽管我认为它是有道理的。我会尝试在谷歌上搜索一些硬数据。
      • 你能分享图表的链接吗?谢谢。
      【解决方案5】:

      意识到 64 位 JVM 并不是制作 Java 应用程序的神奇小精灵 走得更快。 64 位 JVM 允许堆 >> 4 GB,因此才有意义 对于可以利用系统上的巨大内存的应用程序 拥有它。

      通常会有轻微的改进(由于某些硬件 某些平台上的优化)或轻微降级(由于增加 指针大小)。一般来说,需要更少的 GC——但是 当它们确实发生时,它们可能会更长。

      在内存数据库或搜索引擎中可以使用增加的内存 用于缓存对象,从而避免 IPC 或磁盘访问将看到最大 应用程序级别的改进。此外,64 位 JVM 也将 允许您运行比 32 位线程更多的线程,因为 有更多的地址空间用于线程堆栈等。 32 位 JVM 的最大线程数通常为 ~1000,但 64 位 JVM 的最大线程数约为 100000。

      虽然有一些缺点:
      64 位 JVM 的其他问题是某些客户端 面向特性,如 Java Plug-in 和 Java Web Start 不支持。此外,任何本机代码也需要 兼容(例如 JNI 用于类型 II JDBC 驱动程序)。 这对于纯 Java 开发人员来说是一个奖励,因为纯应用程序应该 开箱即用。

      Java.net 上有关此主题的更多信息

      【讨论】:

      • 只是一个注释。 Web start 确实适用于 64 位 JRE 客户端。我已经用 Java 6 和 7 做到了。
      • 现代 JVM 中的线程数(使用本机线程而不是绿色线程)通常受操作系统限制,而不是 JVM。
      猜你喜欢
      • 2010-12-28
      • 2011-06-26
      • 2018-10-25
      • 2012-09-19
      • 2011-12-25
      • 2012-03-17
      • 2013-09-16
      • 1970-01-01
      • 2013-09-13
      相关资源
      最近更新 更多