64位JVM在关键任务的工作负载中是否和32位JVM一样好?

5
我用不同的方式提出了同样的问题,但是问题被关闭了:https://stackoverflow.com/questions/7231460/java-64-bit-or-32-bit。这是我第二次尝试获得客观答案。
我们正在考虑将我们的产品移植到64位Java上,针对那些在Solaris(SPARC)和Linux(RHEL 5.x)上推动32位服务器JVM极限的客户。我们的主管问:“几年前,64位还不太成熟。现在呢?”
  1. 对于那些没有达到4GB边界的客户,使用64位JVM会对性能产生不利影响吗?如果有,影响有多大?我们创建了很多对象。(我们不想同时支持32位和64位JVM。最好是要么这个要么那个。)

  2. 对于那些达到4GB边界的客户,我们可以期望JVM和32位版本一样稳定吗?

    • 性能是否会受到影响?如果有,影响有多大?我们创建了很多对象。
    • 有哪些新的GC调优技术?
    • 分析器:它们可以完全分析64位JVM应用程序吗?
更新:对于那些评论者和关闭我之前问题的人,我现在理解你们的不满。与此同时,我相信你们中的一些人做出了(不真实的)假设,认为我很懒或者是一个没有头绪的人。我将在调查后发布我的发现。感谢所有给我真正指导的人。

6
看起来你在指向的另一个问题上得到了非常好的答案。它们都表明了事实:99.9%的情况下,64位与32位Java并没有什么区别。现在,对于使用64位JVM可以拥有的非常大的堆,是否有不同的调整方式呢?也许是有的。但为什么不直接问这个问题,而不是列举这个棘手的问题清单呢?老实说,这些问题中的大多数使你听起来像是一个不知道自己在谈论什么的人。 - Ernest Friedman-Hill
1
#4 有点无知,字节码没有32位和64位之分。整个情况基本上是一个集成和测试的练习。 - Steve-o
2
你的“工程团队”无法花费几分钟来分析不同的JVM,这有点令人担忧。你不应该不得不问这些问题。 - Steve-o
@Ernest Friedman Hill:我已经将其剪裁到了最基本的部分。在我决定对其进行修剪之前,我不得不两次重新阅读您的问题并看到3个“关闭”投票! - anjanb
@Vineet Reynolds:谢谢。嗯......现在怎么样? - anjanb
显示剩余4条评论
3个回答

5

由于您可以自己进行测试,我假设您期望得到有关使用32/64位JVM的体验的“真实”答案。

我是一个为银行创建金融应用程序的团队的一部分。我们在Windows上使用32位JVM进行开发,并且几乎所有的服务器应用程序都在运行64位JVM的RHEL上。性能对我们来说从未是问题,因为我们使用像样的机器(我们的常规服务器机器使用至少32 GiB RAM的32核AMD盒子)。

正如预期的那样,由于指针大小的差异,堆大小会增加,但由于现在限制已从4GiB提高,这再次不会困扰我们。我们的应用程序还创建了许多对象。我们使用VisualVM或命令行工具调试应用程序时没有任何问题。关于GC设置,我们使用默认设置,并尝试仅在测量实际上是GC创建问题时才进行更改。为我们常见的分配比应用程序使用的堆大小(8GiB)大得多的堆大小,您将看到每天大约进行一次单个大的GC扫描,这非常好。

我听说JDK 7有一个新的GC算法称为G1垃圾回收器,更适合于服务器应用程序,因此您应该尝试一下。

总之,您最好的选择是尽可能多地进行测量(在32位和64位机器上使用32位与64位),然后再决定。值得一提的是,我们的组织正在全力推进64位JVM,因为现代服务器应用程序的4GiB对于大多数股票服务器硬件来说相当受限制(至少在我们的领域中是这样)。


谢谢。我想从其他人那里获取真实世界的经验。当然,我们知道我们的应用程序在当前的32位JVM世界中的表现,但我想了解是否有特定的问题需要我知道。我之前尝试在1.6 JVM上的较小的应用程序中使用G1。就1.7而言:由于它非常新,并且Apache对其的报告并不鼓舞人心,因此我们需要在将其推向生产之前先尝试一下。 - anjanb
Apache 报告说有些循环可能被错误地优化。除了默认情况下关闭此优化,Java 6 中也存在同样的 bug。如果在 Java 7 中将其关闭,则会获得与相同代码基础相同的结果和大致相同的性能。Java 6还具有G1收集器,出于这个原因。 - Peter Lawrey

2
我们正在考虑将我们的产品迁移到64位Java,以满足那些在Solaris(SPARC)和Linux(RHEL 5.x)上推动32位服务器JVM极限的客户需求。我们的主管问道:“几年前,64位还不够成熟,现在怎么样了?”Sun公司比Windows早就开始支持64位。1995年发布的Solaris 2.5(与Windows 95同年)在64位方面并不像它本应该有的那么可靠。许多仍在使用SunOS(32位)的人认为这没有意义,而且很少有机器需要更多的内存。1997年发布的Solaris 2.6看到了第一个重要的64位平台迁移。我直到1999年才开始认真使用Java(在Solaris上),那时64位已经在我的脑海中确立了。

1)对于那些没有超过4GB边界的客户,使用64位JVM是否会对性能产生负面影响?如果是,程度如何?

64位JVM的寄存器大小是32位的两倍,数量也是两倍。如果您经常使用long类型,您可以看到显著的改进,然而对于典型应用程序来说,差别在5-10%之间。

我们创建了很多对象。
在我看来,如果这对您来说不是一个问题,那么性能就不是一个大问题。使用任何分析工具,都有两个报告:CPU 和内存使用情况。通常,检查内存配置文件会更加影响性能。(见下文)
(我们最好不要同时支持32位和64位的JVM。这是一个二选一的情况,最好如此) 不能说有太大的区别。您认为支持每个的开销是多少?代码完全相同,从您的角度来看,它可能会稍微增加测试。这与支持两个Java 6版本没有太大区别。
对于那些推动4GB边界的人,我们可以期望JVM与32位一样稳定吗?
自1999年以来,我使用64位版本,我无法记得有什么情况下使用32位会使事情变得更好(只会因为内存有限而变得更糟)。
性能是否成为问题?如果是,减少丢弃对象。
有哪些GC调优技术是新的?
您可以将最大内存大小设置得更高。这就是全部了。只要保持在32 GB以下,内存使用量不会明显增加,因为它使用32位引用。
我通常会将新应用程序的Eden大小设置为8 GB,如果不需要,就会减少它。这可以大大减少GC时间。(甚至可以降低到每天一次;) 这在32位JVM中是不可能的选择。
关于分析64位JVM应用程序,VisualVM是纯Java,并且据我所知,完全相同。YourKit使用本地库,可能需要确保您正在使用正确的版本(它通常会为您设置这个,但如果您更改了环境,则可能需要知道有两个代理的版本)。
如果您担心性能问题,请不要创建太多对象。您可能会惊讶地发现,在实际应用中自由创建对象会使应用程序变得更慢,可以使应用程序变慢2倍到10倍甚至更多。当我优化代码时,我首先要做的是减少对象的丢弃,并期望至少有三倍的性能提升。
相比之下,使用64位与32位可能会有5%-10%的差异。它可能会更快或更慢,两者同样可能。在内存膨胀方面,请使用最新的JVM,这不太可能被注意到。这是因为64位JVM在使用少于32GB的内存时,默认情况下使用32位引用。头部开销仍然略高,但在启用了-XX:+UseCompressedOops(最新版本的默认设置)时,对象并没有变得更大。

Java:关于64位编程的一切

使用32位和64位JVM测试常见对象的大小 Java:获取对象的大小

一个极端的例子,做同样的事情创建大量对象和反射 vs 不创建任何对象并使用动态生成的代码。1000倍的性能提升。避免Java序列化以提高性能

使用堆内存可以大幅减少GC时间。面向百万元素的集合库

使用更少的堆内存可以让您的应用程序使用更多的内存,而不是将数据传递给另一个应用程序服务器应用程序应该限制自己只使用4GB吗?

1
谢谢。我会浏览您的链接并发布我的反馈,让其他人发现。 - anjanb

1

您的问题涉及到应用程序的多个方面,因此他人的“真实世界”经验可能无法确切告诉您任何有价值的东西。

我的建议是不要浪费时间(也不要浪费我们的时间)询问可能发生的事情,而是看看当您使用64位JVM而不是32位JVM时会发生什么。 无论如何,您都必须进行测试...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接