这是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.
尝试在2G
和3G
之间寻找一个特定大小,我尝试了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)要求单个巨大的内存块吗?(但为什么出现不同的消息)?还是其他什么原因?
\Windows\System32
目录下有64位应用程序。但这不是问题所在——即使我使用C:\Windows\System32\cmd.exe
仍然会发生同样的情况。 - QuantumMechanic