从一方面来看,恐怕我的问题很快就会结束。另一方面,我真的找不到正确的答案。这个问题与我的问题非常接近,但接受的答案在我的案例中是正确的。
Do Java arrays have a maximum size?
举例说明,如果我跑
public static void main(String args[]) {
String[] sa = new String[Integer.MAX_VALUE - 100];
}
使用我目前的Java 9,我会得到:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at...
它必须存在一个很好的解释,而不是Integer.MAX_VALUE - 幻数,但我找不到它。
***编辑
C:\>java -Xms4G -Xmx4G one.ex5
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at one.ex5.main(ex5.java:5)
答案 0 :(得分:1)
这取决于您使用的JVM,参见this回答。
除此之外,错误的原因不是数组的最大允许长度,而是运行时应用程序可用的 Java堆空间不足以初始化数组
使用
-Xmx4G
选项(其中4G代表您希望为应用程序提供的千兆字节的堆空间。只需使用其他值,例如2G或8G或甚至兆字节的值,例如3192M或1024M等)。有关this答案中与内存相关的JVM标志的更多详细信息。
答案 1 :(得分:1)
您混淆了两个概念...... JVM(Java虚拟机)保留空间VS max允许的数组空间。
您收到此错误是因为您的JVM未正确配置为创建此类大小的数组。为此,您可以使用以下参数启动JVM:
-Xms4G -Xmx4G
更多信息:https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html
使用这些参数,您将增加JVM的大小,因此现在您可以创建非常大的数组。
有关信息,max size数组的错误文本(与您的错误文本不同):
java.lang.OutOfMemoryError:
Requested array size exceeds VM limit
您可以在超过数组限制大小时出现此错误。这是“int”而非“整数”,所以理论上它是2 ^ 31-1 = 2147483647,即Integer.MAX_VALUE。但是一些JVM将最大数组值定义为Integer.MAX_VALUE - 5
希望我的回答有点明确......
<强>编辑:强> 如果它仍然无法正常工作,也许你可以用这些方法弄明白:
// Get current size of heap in bytes
long heapSize = Runtime.getRuntime().totalMemory();
// Get maximum size of heap in bytes. The heap cannot grow beyond this size.
// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();
// Get amount of free memory within the heap in bytes. This size will increase // after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();
或者这些工具:Jconsole,VisualVM。
答案 2 :(得分:1)
数组的最大大小由JVM最大堆大小决定
使用我的机器上的默认JVM设置
Runtime.getRuntime()。maxMemory()返回3790077952或3614.5 MiB
通过反复试验,我得到了4字节参考类型数组的以下限制 或4字节基元(我假设字符串引用/指针长4字节)
int numOfBytes = 4; // or 8 64bit JVM maybe ?
int GiB = (1024*1024*1024)/numOfBytes;
int MiB = GiB/1024;
int KiB = MiB/1024;
String[] a = new String[2*GiB+ 662*MiB +1023*KiB+252 /* 1008 bytes*/ ];
// after first allocation JVM allowed me smaller ones
String[] b = new String[59*MiB +613*KiB+ 220/* 880 bytes*/];
String[] c = new String[4*MiB];
// String[] d = new String[1]; <-- fails here
在我的环境中对您的问题的确切答案是
MagicNumber = Integer.MAX_VALUE-2*GiB+ 662*MiB +1023*KiB+252
// MagicNumber == 1784414203
另外,对于long类型的数组,初始最大大小(在我的机器上)是 355335999 只留下大约60 MiB的空闲堆空间