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)

这发生在使用两者的 shell C:\Windows\SystemWOW64\cmd.exe(我错误地认为是 64 位版本)with C:\Windows\System32\cmd.exe(我刚刚发现,由 Pulsar 提供,是一个 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了,它奏效了。随着-Xms2970mJVM崩溃:

#
# 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)是​​否需要一个巨大的内存块?(但是为什么会有不同的消息)?还有什么?

4

2 回答 2

5

SysWoW64 指的是 32bit Windows on Windows 64。简化:在 64 位 Windows 上运行的 32 位 Windows)。

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

请参见:

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

于 2012-06-04T22:14:02.087 回答
4

在 64 位系统中,您有 2^63Bytes 的用户地址空间,但您仍然只能映射您拥有的实际内存量(物理 + 页面文件 + 映射文件)。

当 JVM 创建堆时,它使用 Cmalloc()来请求初始内存块,然后它将自行管理该块。即使堆上根本没有任何对象,对于操作系统来说,块正在被使用。

由于您指定-Xms了 ,这是内存池的最小值,JVM 将简单地尝试从操作系统中请求该数量的内存,或者因为它不能满足您的命令而失败。

我想如果你想看看 64 位 Java 的优势。也许您可以尝试打开大于 4GB 的文件进行随机访问并将其映射到 MappedByteBuffer。

于 2012-06-05T00:27:20.653 回答