Jim C
Jim C

Reputation: 4385

how properly discover the maximun size allowed for an array

From one side I am afraid my question will downvote soon and close. On another hand I really couldn't find the correct answer. This question is very close to mine but the answer accepted is fae away to be true in my case.

Do Java arrays have a maximum size?

To exemplify, if I run

public static void main(String args[]) {
    String[] sa = new String[Integer.MAX_VALUE - 100];
}

with my current Java 9, I will get:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at...

It must exist a good explanation instead of a Integer.MAX_VALUE - magic number but I just can't find it.

*** edited

C:\>java -Xms4G -Xmx4G one.ex5
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at one.ex5.main(ex5.java:5)

Upvotes: 1

Views: 730

Answers (3)

AdnanM91
AdnanM91

Reputation: 66

Maksimum size of array is determined by JVM max heap size

With default JVM settings on my machine

Runtime.getRuntime().maxMemory() returns 3790077952 or 3614.5 MiB

By trial and error I got following limits for array of 4 byte reference type or 4 byte primitive( I assume that string references/pointers are 4 byte long)

    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

So exact answer on your question in my environment is

   MagicNumber = Integer.MAX_VALUE-2*GiB+ 662*MiB +1023*KiB+252 
   // MagicNumber == 1784414203

additionally initial maximum size (on my machine) for array of long type is 355335999 leaving only about 60 MiB of free heap space

Upvotes: 2

jpmottin
jpmottin

Reputation: 3017

You are confusing two notions... JVM (Java Virtual Machine) reserved space VS max allowed space for an array.

You got this error because your JVM are not properly configured to create an array of such size. To do that, you can launch you JVM with some parameters like :

-Xms4G -Xmx4G

More infos : https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html

With these parameters, you will increase the size of your JVM, and so now you are able create very big arrays.

For information, the error text for max size array is (not the same as yours):

java.lang.OutOfMemoryError:
  Requested array size exceeds VM limit

You can have this error you exceed the limit size of an array. And this is "int" not "Integer", so theoretically it is 2^31-1 = 2147483647, which is Integer.MAX_VALUE. But some JVM has defined max array value as Integer.MAX_VALUE - 5

Hope my answer is somehow clear...

Edited: And if it's still not working, maybe you can figure it out with these lines :

// 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();

Or these tools: Jconsole, VisualVM.

Upvotes: 1

DeBukkIt
DeBukkIt

Reputation: 102

This depends on the JVM you use, cf. this answer.


Apart from that, the reason for your error is not the maximum allowed length of an array, but the fact that the Java heap space available to your application at runtime was not sufficient to initialize your array.

Use the

-Xmx4G

option (where 4G stands for the heap space in gigabytes that you want to make available to the application. Just use other values, for example 2G or 8G or even values ​​in megabytes, e.g. 3192M or 1024M etc.). More details on memory relevant JVM flags in this answer.

Upvotes: 1

Related Questions