无法在64位Windows 7上以大堆大小运行64位JVM

10

这是64位的Windows 7 Enterprise和64位的Java 7:

java version "1.7.0_04"
Java(TM) SE Runtime Environment (build 1.7.0_04-b20)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)

使用 C:\Windows\SystemWOW64\cmd.exe(我错误地认为它是64位版本)C:\Windows\System32\cmd.exe shell 都会出现此问题(我刚刚通过 Pulsar 的提示发现,尽管路径名中有“32”,但它是一个64位应用程序)。

程序本身是微不足道的:

public class Trivial
{
    public static void main(String[] args) {
        System.out.println("total = " + toMB(Runtime.getRuntime().totalMemory()));
        System.out.println("max   = " + toMB(Runtime.getRuntime().maxMemory()));
    }

    private static long toMB(long bytes) {
        return bytes / (1024L * 1024L);
    }
}

我只是试着改变不同的-Xmx-Xms参数,看看会发生什么。我本以为在64位Windows上使用64位Java时,无论我想要多大的最大堆和初始堆都可以,但现实并非如此。

java -Xmx16G -Xms2G Trivial(例如)运行良好。然而,java -Xmx16G -Xms4G Trivial却给了我以下错误信息:

Error occurred during initialization of VM
Could not reserve enough space for object heap

对我来说更奇怪的是,java -Xmx16G -Xms3G Trivial会给出不同的错误:

Error occurred during initialization of VM
Unable to allocate tables for parallel garbage collection for the requested heap size.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

尝试在2G3G之间寻找一个特定大小,我尝试了java -Xmx16G -Xms2900M Trivial,它起作用了。然后我尝试了-Xms2960M,它也起作用了。但是使用-Xms2970m时,JVM崩溃了:

#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 1048576 bytes for E in C:\jdk7u2_64p\jdk7u4\hotspot\src\share\vm\utilities/taskqueue.hpp
# An error report file with more information is saved as:
# C:\Users\QuantumMechanic\Temp\hs_err_pid10780.log

直到-Xms2995M时,它又切换回“无法为并行垃圾回收分配表”的消息,并随着-Xms的进一步增加而停滞不前。

发生了什么?从cmd.exe启动某些内容(即使是64位的)是否会施加一些进程大小限制?是Windows(还是JVM)要求单个巨大的内存块吗?(但为什么出现不同的消息)?还是其他什么原因?

2个回答

5

SysWoW64是指运行在64位Windows操作系统上的32位Windows。简单来说,就是在64位Windows上运行32位的Windows。

因此,您明确要求在32位cmd shell中运行。

请参见:

http://en.wikipedia.org/wiki/WoW64


谢谢提供的信息。我之前不知道\Windows\System32目录下有64位应用程序。但这不是问题所在——即使我使用C:\Windows\System32\cmd.exe仍然会发生同样的情况。 - QuantumMechanic

4
在64位系统中,您拥有2^63字节的用户地址空间,但您仍然只能映射实际内存量(物理内存+页面文件+映射文件)。
当JVM创建堆时,它使用C malloc()请求初始块内存,然后自行管理该块即使在堆上没有任何对象,对于操作系统而言该块也正在被使用。
由于您指定了-Xms,这是内存池最小值,因此JVM将尝试从操作系统获取该内存量或者因为无法满足命令而失败。
我想如果您想看到64位Java的优势。也许您可以尝试打开一个大于4GB的文件进行随机访问,并将其映射到MappedByteBuffer中。

一个可能的交换空间限制。我没有想到过这一点。明天回到工作岗位后,我会检查那台电脑上的页面文件大小设置,并查看它的设置情况。 - QuantumMechanic
3
这是一个关于交换文件大小的问题。由于某些原因,我所使用的电脑上的页面文件大小被设置为4GB,而非自动管理。该计算机的RAM为8GB,所以最多只有12GB的虚拟内存可用,当然还有很多其他程序在运行。当我增加了页面文件的大小后,就可以设定更高的"-Xms"值了。 - QuantumMechanic

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