JVM 是 32 位还是 64 位?
32 OR 64 BIT for the JVM?
这本书读完了 here。
我可以看到以下部分:
32 OR 64 BIT? If you have a 32-bit operating system, then you must use
a 32-bit version of the JVM. If you have a 64-bit operating system,
then you can choose to use either the 32- or 64-bit version of Java.
Don’t assume that just because you have a 64-bit operating system, you
must also use a 64-bit version of Java.
If the size of your heap will be less than about 3 GB, the 32-bit
version of Java will be faster and have a smaller footprint. This is
because the memory references within the JVM will be only 32-bits, and
manipulating those memory references is less expensive than
manipulating 64-bit references (even if you have a 64-bit CPU). The
32-bit references also use less memory.
Chapter 8 discusses compressed oops, which is a way that the JVM can
use 32-bit addresses even within the 64-bit JVM. However, even with
that optimization, the 64-bit JVM will have a larger footprint because
the native code it uses will still have 64-bit addresses.
The downside to the 32-bit JVM is that the total process size must be
less than 4GB (3GB on some versions of Windows, and 3.5GB on some old
versions of Linux). That includes the heap, permgen, and the native
code and native memory the JVM uses. Programs that make extensive use
of long or double variables will be slower on a 32-bit JVM because
they cannot use the CPU’s 64-bit registers, though that is a very
exceptional case.
Programs that fit within a 32-bit address space will run anywhere
between 5% and 20% faster in a 32-bit JVM than a similarly-configured
64-bit JVM. The stock batching program discussed earlier in this
chapter, for example, is 20% faster when run on a 32-bit JVM on my
desktop.
这些行表示 32 位对于较小的堆大小(小于 3GB)会更快。如果这是真的,我想知道背后的原因,是什么让 32 位 JVM 更快?
32 位内存地址更小。仅此一项就可能导致更好的缓存、参考位置等。
32 位地址少内存 space 最大理论限制是 4GB 但实际上在 Windows 系统中是 1.3GB。您可以在 Linux 内核上解决更多(300 到 400 MB)的问题。有关详细信息,请使用 http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit(堆 Space 内存)
64位使用高位寻址。所以整体内存消耗也更高。可以选择使用压缩内存指针。在 http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#compressedOop
阅读更多相关信息
64 位速度较慢的原因是大量垃圾收集暂停。建立更多的堆意味着 GC 在清除未使用的对象时需要完成更多的工作。这在现实生活中意味着在构建大于 12-16GB 的堆时必须格外小心。如果不进行微调和测量,您可以轻松引入跨越几分钟的完整 GC 暂停。
我对作者声称使用 32 位版本的 JVM 会带来 5% 到 20% 的性能提升持怀疑态度。但是,我不经常使用 Java 所以我不确定。但是为了调查这个说法,我查看了 SPEC 的一些结果。
我搜索了 SPECjEnterprise2010 结果,x86-64 架构的最高分是 an Oracle system that used a 64-bit version of the JVM。
我还查看了 SPECjvm2008,以防这些较小的工作负载可能受益于 32 位架构。但是 best performing x86-64 system, this time from Huawei, 再次使用了 64 位版本的 JVM。
如果 32 位版本的 JVM 真的更好,我希望提交他们的 SPEC 结果的人在调整他们的工作负载时会选择它(但我可能是错的)。
我不怀疑 32 位版本的 JVM 在某些工作负载上的性能优于 64 位版本。正如其他人所指出的,它使用更多的地址内存。然而,x86-64 架构有更多可用的寄存器,我怀疑 64 位操作模式是大部分优化工作的重点。
系统性能有很多组成部分,我不认为 32 位版本的 JVM 一定会优于 64 位版本(其中之一,这只对 CPU 绑定的工作负载有影响).我想说的是,如果您在性能调优过程中到了这一步,您会想要检查您自己的工作负载是否有两个不同的选项,并使用您自己的测试结果来做出决定,而不是假设使用 32 -bit 优于 64 位,因为根据经验可以节省地址的内存 space,因为还有其他因素可能比这更重要。
更多的是一般性能的问题。如果你有一个最新的 64 位处理器和大量未使用的内存,使用 JVM 32 而不是 JVM 64 的唯一可能的好处是一些循环可以完全适合 32 位地址的缓存而不是 64 位地址导致更少的主内存使用 32 位 JVM 访问。我真的无法评估收益,但除非在非常特殊的情况下,否则我怀疑它会达到 5% 到 20% - 注意我只是怀疑,不确定 ...
但是如果您使用的是资源有限的系统,最终因为您想要优化您的硬件和 运行 上面的许多虚拟机,32 位 JVM 将使用比 64 位 JVM 少得多的内存。它将为其他应用程序和系统留出更多空闲内存,从而避免交换并允许系统更好地缓存磁盘 IO。
恕我直言,没有一般规则。我只会使用以下经验法则:如果当 JVM 和所有其他应用程序 处于 运行ning 时,系统仍然有足够的内存来缓存 IO,我会使用 64位 JVM,在相反的情况下是 32 位。
当然,只有当 Java 应用程序本身不需要大量内存强制使用 64 位 JVM 并最终在必要时向系统添加更多内存时,以上内容才有意义,因为内存现在没那么贵了
没有简单的答案,最好的办法是针对您的特定应用进行尝试。但是您应该记住,还有很多其他选择,例如关于 JIT、垃圾收集算法、RAM 限制,这可能比架构的选择产生更大的影响,因此您必须将这些包括在您的测量中。
如果您曾经问过这个问题,换句话说,您有 选择,这意味着您已经 运行 在具有 32 位模式的 64 位系统上(具有可接受的性能,即没有软件仿真)这很可能是 AMD64 又名 x86-64。
在此类系统上,Oracle 的 JVM 支持“压缩 oops”,这意味着在 Java 堆中使用 32 位引用,只要最大堆不超过 32 GB(如果超过,我怀疑使用 32 Bit 是该应用程序的有效选择)。与 32 位 JVM 相比,它可能仍会消耗更多 RAM,因为某些组件仍需要使用 64 位指针,但这些通常不是应用程序的性能相关部分。
请注意,对于 AMD64 aka x86-64 架构,使用 64 位模式意味着不仅仅是更改指针大小。注意只允许每个寄存器使用 64 位,它还有 更多 个可用寄存器。它实际上是在同一芯片中实现的不同架构,具体取决于您的应用程序,启用它可能是一个很大的改进。
但如前所述,使用您的真实应用程序对其进行测试是获得正确答案的唯一有效方法。
如果您打算使用其中一个 Oracle VM,那么问题就变成了您是要使用客户端还是服务器 JIT,因为 Oracle 还没有可用于任何 64 位 CPU 的客户端 JIT .
服务器 VM 可用于 32 位和 64 位 CPUs,服务器 VMs 在 x86/AMD64 CPUs 上的性能差异相当小(根据我的经验,这是在 Windows 或 Linux 上少于 +/-5%),尽管 64 位虚拟机通常需要大约 20% 的内存。
如果您的应用程序需要超过 1.3GB 的堆内存大小,您将不得不使用 64 位服务器 VM,因为来自 Oracle 的 32 位 VM 不会以大于该大小的堆内存开始(在 Linux极限略高)。
客户端 JIT 的主要优点是启动时间更快。使用此 VM,您可以在不到 100 毫秒的时间内完成大量重要工作,而服务器 VM 仅需一秒以上即可启动,即使启用了分层编译。客户端 VM 还需要比服务器 VM 少得多的内存,并且可以在同一台计算机上的多个 VM 实例之间受益class data sharing。
另一方面,服务器 VM 往往能够以相当快的速度执行计算密集型代码。实际性能差异很大,具体取决于您执行的代码,但可能介于 -10% 和 +200% 之间。通常,对于任何需要超过几百毫秒才能达到 运行.
的东西,它至少要快 30%
您可以使用各种选项调整两个 JIT,使它们的行为更加相似,但您仍然只有客户端 VM 才能获得快速启动时间,只有服务器 VM 才能获得最高执行速度。
因此,如果您有足够的可用内存并且不关心启动时间损失,我建议您对所有内容都使用 64 位服务器 VM。 32 位客户端 VM 非常适合较小的 GUI 应用程序,但尤其适用于平均执行时间不到一秒或可能需要 运行 在同一台计算机上同时执行多次的小型命令行工具。
选择 64 位的一个论据是,如今 32 位服务器硬件非常少见。因此,在服务器上使用 32 位软件的人并不多。 32 位 jvms 仍然存在的主要原因是支持旧 32 位系统的 32 位客户端软件以及 applet,运行 通过 32 位浏览器中的插件。
因此,如果 32 位版本中潜伏着奇异的错误,您可能是第一个发现的。这些错误类型在桌面系统上不太明显,而在长 运行ning 服务器端软件中更明显。想想几次 weeks/days 后神秘的崩溃。内存泄漏等
因此,如果您要在服务器上进行部署,除非您有非常充分的理由不这样做,否则几乎可以选择 64 位。当涉及到 Java 的内存使用和垃圾收集时,有很多蛇油解决方案。所以,无论哪种方式,我都会谨慎地使用它作为论据,除非你可以用一些可靠的指标来支持它。根据我的经验,java 知道如何正确调优 jvm 的工程师实际上很少见,而且大多数人似乎只是随机复制粘贴在 JVM_ARGS 上的东西,直到它起作用为止。他们中的大多数人最终用不是最优的、不再适合他们使用的 JVM 或有害的解决方案搬起石头砸自己的脚。 Jvm调优有点黑魔法。除非你知道自己在做什么,否则最好不要弄乱它。
对于客户端系统,如果您需要支持小程序或较旧的桌面系统,请选择 32 位。例如。 windows 直到最近才推出其 OS 的 32 位版本,windows 和 osx 上的许多应用程序仍然是 32 位的。大多数情况下,您不必选择,在任何情况下,您都可以将此选择权留给用户。
对于担心地址大小的人,64位版本可以对小于32GB的堆进行指针压缩。您需要(并且可能想要)在 JVM args 中打开它:-XX:+UseCompressedOops.
。
这本书读完了 here。
我可以看到以下部分:
32 OR 64 BIT? If you have a 32-bit operating system, then you must use a 32-bit version of the JVM. If you have a 64-bit operating system, then you can choose to use either the 32- or 64-bit version of Java. Don’t assume that just because you have a 64-bit operating system, you must also use a 64-bit version of Java.
If the size of your heap will be less than about 3 GB, the 32-bit version of Java will be faster and have a smaller footprint. This is because the memory references within the JVM will be only 32-bits, and manipulating those memory references is less expensive than manipulating 64-bit references (even if you have a 64-bit CPU). The 32-bit references also use less memory.
Chapter 8 discusses compressed oops, which is a way that the JVM can use 32-bit addresses even within the 64-bit JVM. However, even with that optimization, the 64-bit JVM will have a larger footprint because the native code it uses will still have 64-bit addresses.
The downside to the 32-bit JVM is that the total process size must be less than 4GB (3GB on some versions of Windows, and 3.5GB on some old versions of Linux). That includes the heap, permgen, and the native code and native memory the JVM uses. Programs that make extensive use of long or double variables will be slower on a 32-bit JVM because they cannot use the CPU’s 64-bit registers, though that is a very exceptional case.
Programs that fit within a 32-bit address space will run anywhere between 5% and 20% faster in a 32-bit JVM than a similarly-configured 64-bit JVM. The stock batching program discussed earlier in this chapter, for example, is 20% faster when run on a 32-bit JVM on my desktop.
这些行表示 32 位对于较小的堆大小(小于 3GB)会更快。如果这是真的,我想知道背后的原因,是什么让 32 位 JVM 更快?
32 位内存地址更小。仅此一项就可能导致更好的缓存、参考位置等。
32 位地址少内存 space 最大理论限制是 4GB 但实际上在 Windows 系统中是 1.3GB。您可以在 Linux 内核上解决更多(300 到 400 MB)的问题。有关详细信息,请使用 http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit(堆 Space 内存)
64位使用高位寻址。所以整体内存消耗也更高。可以选择使用压缩内存指针。在 http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#compressedOop
阅读更多相关信息64 位速度较慢的原因是大量垃圾收集暂停。建立更多的堆意味着 GC 在清除未使用的对象时需要完成更多的工作。这在现实生活中意味着在构建大于 12-16GB 的堆时必须格外小心。如果不进行微调和测量,您可以轻松引入跨越几分钟的完整 GC 暂停。
我对作者声称使用 32 位版本的 JVM 会带来 5% 到 20% 的性能提升持怀疑态度。但是,我不经常使用 Java 所以我不确定。但是为了调查这个说法,我查看了 SPEC 的一些结果。
我搜索了 SPECjEnterprise2010 结果,x86-64 架构的最高分是 an Oracle system that used a 64-bit version of the JVM。
我还查看了 SPECjvm2008,以防这些较小的工作负载可能受益于 32 位架构。但是 best performing x86-64 system, this time from Huawei, 再次使用了 64 位版本的 JVM。
如果 32 位版本的 JVM 真的更好,我希望提交他们的 SPEC 结果的人在调整他们的工作负载时会选择它(但我可能是错的)。
我不怀疑 32 位版本的 JVM 在某些工作负载上的性能优于 64 位版本。正如其他人所指出的,它使用更多的地址内存。然而,x86-64 架构有更多可用的寄存器,我怀疑 64 位操作模式是大部分优化工作的重点。
系统性能有很多组成部分,我不认为 32 位版本的 JVM 一定会优于 64 位版本(其中之一,这只对 CPU 绑定的工作负载有影响).我想说的是,如果您在性能调优过程中到了这一步,您会想要检查您自己的工作负载是否有两个不同的选项,并使用您自己的测试结果来做出决定,而不是假设使用 32 -bit 优于 64 位,因为根据经验可以节省地址的内存 space,因为还有其他因素可能比这更重要。
更多的是一般性能的问题。如果你有一个最新的 64 位处理器和大量未使用的内存,使用 JVM 32 而不是 JVM 64 的唯一可能的好处是一些循环可以完全适合 32 位地址的缓存而不是 64 位地址导致更少的主内存使用 32 位 JVM 访问。我真的无法评估收益,但除非在非常特殊的情况下,否则我怀疑它会达到 5% 到 20% - 注意我只是怀疑,不确定 ...
但是如果您使用的是资源有限的系统,最终因为您想要优化您的硬件和 运行 上面的许多虚拟机,32 位 JVM 将使用比 64 位 JVM 少得多的内存。它将为其他应用程序和系统留出更多空闲内存,从而避免交换并允许系统更好地缓存磁盘 IO。
恕我直言,没有一般规则。我只会使用以下经验法则:如果当 JVM 和所有其他应用程序 处于 运行ning 时,系统仍然有足够的内存来缓存 IO,我会使用 64位 JVM,在相反的情况下是 32 位。
当然,只有当 Java 应用程序本身不需要大量内存强制使用 64 位 JVM 并最终在必要时向系统添加更多内存时,以上内容才有意义,因为内存现在没那么贵了
没有简单的答案,最好的办法是针对您的特定应用进行尝试。但是您应该记住,还有很多其他选择,例如关于 JIT、垃圾收集算法、RAM 限制,这可能比架构的选择产生更大的影响,因此您必须将这些包括在您的测量中。
如果您曾经问过这个问题,换句话说,您有 选择,这意味着您已经 运行 在具有 32 位模式的 64 位系统上(具有可接受的性能,即没有软件仿真)这很可能是 AMD64 又名 x86-64。
在此类系统上,Oracle 的 JVM 支持“压缩 oops”,这意味着在 Java 堆中使用 32 位引用,只要最大堆不超过 32 GB(如果超过,我怀疑使用 32 Bit 是该应用程序的有效选择)。与 32 位 JVM 相比,它可能仍会消耗更多 RAM,因为某些组件仍需要使用 64 位指针,但这些通常不是应用程序的性能相关部分。
请注意,对于 AMD64 aka x86-64 架构,使用 64 位模式意味着不仅仅是更改指针大小。注意只允许每个寄存器使用 64 位,它还有 更多 个可用寄存器。它实际上是在同一芯片中实现的不同架构,具体取决于您的应用程序,启用它可能是一个很大的改进。
但如前所述,使用您的真实应用程序对其进行测试是获得正确答案的唯一有效方法。
如果您打算使用其中一个 Oracle VM,那么问题就变成了您是要使用客户端还是服务器 JIT,因为 Oracle 还没有可用于任何 64 位 CPU 的客户端 JIT .
服务器 VM 可用于 32 位和 64 位 CPUs,服务器 VMs 在 x86/AMD64 CPUs 上的性能差异相当小(根据我的经验,这是在 Windows 或 Linux 上少于 +/-5%),尽管 64 位虚拟机通常需要大约 20% 的内存。
如果您的应用程序需要超过 1.3GB 的堆内存大小,您将不得不使用 64 位服务器 VM,因为来自 Oracle 的 32 位 VM 不会以大于该大小的堆内存开始(在 Linux极限略高)。
客户端 JIT 的主要优点是启动时间更快。使用此 VM,您可以在不到 100 毫秒的时间内完成大量重要工作,而服务器 VM 仅需一秒以上即可启动,即使启用了分层编译。客户端 VM 还需要比服务器 VM 少得多的内存,并且可以在同一台计算机上的多个 VM 实例之间受益class data sharing。
另一方面,服务器 VM 往往能够以相当快的速度执行计算密集型代码。实际性能差异很大,具体取决于您执行的代码,但可能介于 -10% 和 +200% 之间。通常,对于任何需要超过几百毫秒才能达到 运行.
的东西,它至少要快 30%您可以使用各种选项调整两个 JIT,使它们的行为更加相似,但您仍然只有客户端 VM 才能获得快速启动时间,只有服务器 VM 才能获得最高执行速度。
因此,如果您有足够的可用内存并且不关心启动时间损失,我建议您对所有内容都使用 64 位服务器 VM。 32 位客户端 VM 非常适合较小的 GUI 应用程序,但尤其适用于平均执行时间不到一秒或可能需要 运行 在同一台计算机上同时执行多次的小型命令行工具。
选择 64 位的一个论据是,如今 32 位服务器硬件非常少见。因此,在服务器上使用 32 位软件的人并不多。 32 位 jvms 仍然存在的主要原因是支持旧 32 位系统的 32 位客户端软件以及 applet,运行 通过 32 位浏览器中的插件。
因此,如果 32 位版本中潜伏着奇异的错误,您可能是第一个发现的。这些错误类型在桌面系统上不太明显,而在长 运行ning 服务器端软件中更明显。想想几次 weeks/days 后神秘的崩溃。内存泄漏等
因此,如果您要在服务器上进行部署,除非您有非常充分的理由不这样做,否则几乎可以选择 64 位。当涉及到 Java 的内存使用和垃圾收集时,有很多蛇油解决方案。所以,无论哪种方式,我都会谨慎地使用它作为论据,除非你可以用一些可靠的指标来支持它。根据我的经验,java 知道如何正确调优 jvm 的工程师实际上很少见,而且大多数人似乎只是随机复制粘贴在 JVM_ARGS 上的东西,直到它起作用为止。他们中的大多数人最终用不是最优的、不再适合他们使用的 JVM 或有害的解决方案搬起石头砸自己的脚。 Jvm调优有点黑魔法。除非你知道自己在做什么,否则最好不要弄乱它。
对于客户端系统,如果您需要支持小程序或较旧的桌面系统,请选择 32 位。例如。 windows 直到最近才推出其 OS 的 32 位版本,windows 和 osx 上的许多应用程序仍然是 32 位的。大多数情况下,您不必选择,在任何情况下,您都可以将此选择权留给用户。
对于担心地址大小的人,64位版本可以对小于32GB的堆进行指针压缩。您需要(并且可能想要)在 JVM args 中打开它:-XX:+UseCompressedOops.
。