Why I can't create an array with large size?
Why it is impossible to create an array with max int size?
int i = 2147483647;
int[] array = new int[i];
I found this explanation:
Java arrays are accessed via 32-bit ints, resulting in a maximum theoretical array size of 2147483647 elements.
But as you can see my code doesn't work. It is also impossible to create an array with size
new int[Integer.MAX_VALUE - 5];
Technical details
- 64-Bit HotSpot JVM
- OSX 10.10.4
PS
And why -5
actually?
Theory
There are two possible exceptions:
-
OutOfMemoryError: Java heap space
means your array does not fit into java heap space. In order to solve you can increase the maximum heap size by using JVM option-Xmx
. Also take into account that the maximum size of object cannot be larger than the largest heap generation. -
OutOfMemoryError: Requested array size exceeds VM limit
means platform-specific size was exceeded:- the upper bound limit is set by the restrictions of the size type used to describe an index in the array, so theoretical array size is limited by
2^31-1=2147483647
elements. - the other limit is JVM/platform specific. According to chapter 10: Arrays of The Java Language Specification, Java SE 7 Edition there is no strict limit on array length, thus array size may be reduced without violating JLS.
- the upper bound limit is set by the restrictions of the size type used to describe an index in the array, so theoretical array size is limited by
Practice
In HotSpot JVM array size is limited by internal representation. In the GC code JVM passes around the size of an array in heap words as an int
then converts back from heap words to jint
this may cause an overflow. So in order to avoid crashes and unexpected behavior the maximum array length is limited by (max size - header size). Where header size depends on C/C++ compiler which was used to build the JVM you are running(gcc for linux, clang for macos), and runtime settings(like UseCompressedClassPointers
). For example on my linux:
- Java HotSpot(TM) 64-Bit Server VM 1.6.0_45 limit
Integer.MAX_VALUE
- Java HotSpot(TM) 64-Bit Server VM 1.7.0_72 limit
Integer.MAX_VALUE-1
- Java HotSpot(TM) 64-Bit Server VM 1.8.0_40 limit
Integer.MAX_VALUE-2
Useful Links
- https://bugs.openjdk.java.net/browse/JDK-8059914
- https://bugs.openjdk.java.net/browse/JDK-8029587
Some VMs reserve some header words in an array.
The maximum "safe" number would be 2 147 483 639 (Integer.MAX_VALUE - 8)
Source-http://www.docjar.com/html/api/java/util/ArrayList.java.html
**
191 * The maximum size of array to allocate.
192 * Some VMs reserve some header words in an array.
193 * Attempts to allocate larger arrays may result in
194 * OutOfMemoryError: Requested array size exceeds VM limit
195 */
196 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
So It depends on the maximum memory available to your JVM on your SYSTEM NOW
Edit : Why It's Showing OOM.
Number of Elements = 2 147 483 639
number of bytes required for one element = 4
Total Memory for just Element 8589934556 KB == 8.589934555999999 GB
Now If the total memory usage of the array is not a multiple of 8 bytes, then the size is rounded up to the next mutlitple of 8 .
So You need more than what you are allocating due to Overheads too and that should be continuous memory
It's not enough to just have enough heap for that allocation; you need to have a single heap region of sufficient size. As you know, heap is divided into generations.
For a single allocation of 8 GB you must ensure that much for a single heap region (plus some overhead). With 12 GB of -Xmx
you may still be short. Use additional options to control the size of the Old Generation.