如何正确发现阵列允许的最大尺寸

时间:2018-01-10 14:30:30

标签: java

从一方面来看,恐怕我的问题很快就会结束。另一方面,我真的找不到正确的答案。这个问题与我的问题非常接近,但接受的答案在我的案例中是正确的。

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)

3 个答案:

答案 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的空闲堆空间