Reputation: 4385
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
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
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
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