我有一台 Windows 7 x64 笔记本电脑,其中使用 VirtualBox 安装了 Windows XP x32 客户虚拟机。有一次我在客户机上运行了一个应用程序,发现它的运行速度明显比在主机上快。这是为什么呢?
答案1
既然您提到了 Java,那么您的 JVM 的版本是什么,它在主机上是以 32 位还是 64 位模式运行的?
压缩错误
“oop”,或者普通对象指针用 Java Hotspot 的说法,是指向对象的托管指针。oop 通常与本机机器指针大小相同,这意味着在 LP64 系统上为 64 位。在 ILP32 系统上,最大堆大小略小于 4 GB,这对于许多应用程序来说是不够的。在 LP64 系统上,给定程序使用的堆可能必须比在 ILP32 系统上运行时大 1.5 倍左右。此要求是由于托管指针的大小扩大。内存很便宜,但如今带宽和缓存供不应求,因此大幅增加堆的大小并仅超过 4 GB 的限制是不可取的。
Java 堆中的托管指针指向与 8 字节地址边界对齐的对象。压缩 oop 将托管指针(在 JVM 软件中的许多地方,但不是所有地方)表示为距离 64 位 Java 堆基地址的 32 位对象偏移量。因为它们是对象偏移量而不是字节偏移量,所以它们可用于寻址多达 40 亿个对象(不是字节),或最大约 32 GB 的堆大小。要使用它们,必须将它们按 8 倍缩放并添加到 Java 堆基地址以查找它们引用的对象。使用压缩 oop 的对象大小与 ILP32 模式下的对象大小相当。
期限解码用于表达将 32 位压缩 oop 转换为托管堆中的 64 位本机地址的操作。逆操作称为编码。
Java SE 6u23 及更高版本默认支持并启用压缩 oop。在 Java SE 7 中,当
-Xmx
未指定且值-Xmx
小于 32 GB 时,64 位 JVM 进程默认使用压缩 oop。对于 6u23 版本之前的 JDK 6,请使用-XX:+UseCompressedOops
java 命令中的标志来启用该功能。
64 位 JVM 占用的内存较大,对性能有非常大的影响。
答案2
由于缓存,应用程序在 VM 中的运行速度可能会更快。由于 VM 将其磁盘存储在文件中,主机操作系统可能会将这些文件缓存在 RAM 中,因此它们的运行速度会明显加快。32 位和 64 位应用程序之间的实际差异只有几个百分点。