246

Is there a limit to the number of elements a Java array can contain? If so, what is it?

Pops
  • 30,199
  • 37
  • 136
  • 151
Lizard
  • 43,732
  • 39
  • 106
  • 167

10 Answers10

205

Using

OpenJDK 64-Bit Server VM (build 15.0.2+7, mixed mode, sharing)

... on MacOS, the answer seems to be Integer.MAX_VALUE - 2. Once you go beyond that:

cat > Foo.java << "END"
public class Foo {
  public static void main(String[] args) {
    boolean[] array = new boolean[Integer.MAX_VALUE - 1]; // too big
  }
}
END
java -Xmx4g Foo.java

... you get:

Exception in thread "main" java.lang.OutOfMemoryError:
  Requested array size exceeds VM limit
Kevin Bourrillion
  • 40,336
  • 12
  • 74
  • 87
  • 65
    I think the idea of downvotes makes no sense unless we are willing to downvote answers that are plain and simply _wrong_. Does the difference of five bytes actually matter in the real world, NO, of course not. But it concerns me that people are willing to give an answer "authoritatively" without even trying it to see if it really works. As for the memory limit, well, DUH. That's like if you asked me "how many grapes can you eat?" and I said "well, it depends on how many I have in the fridge at the time." – Kevin Bourrillion Jun 16 '10 at 15:30
  • Sry I'm not understanding your answer.. do you mean to say that the maximum is MAX_VALUE - 5 even if my machine has the required memory to create an int the size of MAX_VALUE ? – Pacerier Dec 03 '11 at 20:03
  • 2
    @Pacerier, yes, the memory address index is 32bit and there is an object header+length, so they still need to be addressed by that 32bit index. – bestsss Jan 01 '12 at 09:42
  • 7
    Do you happen to know _why_ it won't give you those five bytes? Is this necessarily something that always happens in Java, or could it just be related to your computer's memory or something? – Taymon Jan 01 '12 at 09:44
  • 20
    @Kevin Bourrillion: This seems to have changed, using Oracle 1.7.0_07 I can allocate up to `MAX_VALUE-2` elements. This is independent of what I allocate, and I really wonder what can the VM use the two "things" for (the length doesn't fit in 2 bytes). – maaartinus Sep 28 '12 at 21:58
  • 1
    @bestsss: I don't think so... there may be only 2 spare bytes (see my above comment) and the object header is much bigger. Actually, the JVM can use unsigned ints, so there must be some other reason. – maaartinus Sep 28 '12 at 22:01
  • @KevinBourrillion: Well the five bytes do actually matter in the real world, since you cannot even instance the array (independant of the objects in it). – John Smith Oct 10 '12 at 15:47
  • 2
    @maaartinus, *the object header is much bigger* Object header is (usually) 8bytes+4bytes length. References take 4 bytes on 32bit systems. – bestsss Oct 19 '12 at 11:34
  • 2
    Wait, it runs out of memory. What if you just give it more memory? I want to know about the maximum length without that restraint. In C and Objective C, when you get the array's length, it's represented as a long. – sudo Dec 22 '13 at 17:57
  • Does this limit also apply on strings? – Tomáš Zato Jan 18 '14 at 13:35
  • 3
    @TomášZato the latest at `Integer.MAX_VALUE+1`, you will have an integer overflow. Array sizes in Java are `int`, not `long`; no matter what data type you store in your array, bytes or references. Strings are just Object references. – Has QUIT--Anony-Mousse May 05 '14 at 16:31
  • I'm not sure how to understand this - so does string happen to be encapsulated array of chars or not? – Tomáš Zato May 05 '14 at 19:05
  • 8
    The maximum number of elements in an array in JDK 6 and above is `Integer.MAX_VALUE - 2` = 2 147 483 645. Java successfully allocates such an array if you run it with `-Xmx13G`. It fails with `OutOfMemoryError: Java heap space` if you pass `-Xmx12G`. – Alexey Ivanov Feb 27 '15 at 10:46
  • int arr[] = new int[1000000000]; gives `OutOfMemoryError` – Dhruvam Gupta Nov 19 '16 at 14:49
  • 1
    I guess that future readers may be interested to run eyes over https://stackoverflow.com/questions/48189656/how-properly-discover-the-maximun-size-allowed-for-an-array – Jim C Jan 12 '18 at 14:26
  • @AlexeyIvanov You mean an int array right? Testing in Eclipse Version: 2019-06 (4.12.0), jdk1.8.0_221, I got the same result for an int array, setting the options in a run configuration for the test class, although jvisualvm shows 8GB heap space allocated to the test process. For a boolean array I didn't need to set run config options for the test class with -Xmx1024m set in eclipse.ini, and jvisualvm shows 2GB heap space allocated to the test process. – avg Dec 22 '19 at 18:13
  • @avg I don't remember; likely I was allocating an array of `int`. The required heap size depends on the JVM and chosen GC. Additionally, `boolean` is four times smaller than `int`, and it may be compressed to store 8 values in one byte. – Alexey Ivanov Dec 23 '19 at 21:33
  • I've finally edited the answer with the more current value. 10 entire years after posting it. Thanks @maaartinus and others. – Kevin Bourrillion Nov 12 '22 at 18:51
147

This is (of course) totally VM-dependent.

Browsing through the source code of OpenJDK 7 and 8 java.util.ArrayList, .Hashtable, .AbstractCollection, .PriorityQueue, and .Vector, you can see this claim being repeated:

/**
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

which is added by Martin Buchholz (Google) on 2010-05-09; reviewed by Chris Hegarty (Oracle).

So, probably we can say that the maximum "safe" number would be 2 147 483 639 (Integer.MAX_VALUE - 8) and "attempts to allocate larger arrays may result in OutOfMemoryError".

(Yes, Buchholz's standalone claim does not include backing evidence, so this is a calculated appeal to authority. Even within OpenJDK itself, we can see code like return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; which shows that MAX_ARRAY_SIZE does not yet have a real use.)

Alexey Ivanov
  • 11,541
  • 4
  • 39
  • 68
Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • And why we need to add `-8`? – JohnWinter Jul 13 '15 at 12:21
  • @Pacerier. Shouldn't this MAX_ARRAY_SIZE be applied only when you are using an ArrayList? That is different from using an array like int[] array = new int[some_value_here]; isn't it? Why can a constant defined in ArrayList be applied to a normal array (defined with [])? Are they the same behind the scenes? – Bitcoin Cash - ADA enthusiast Sep 03 '15 at 00:04
  • 1
    @Tiago, No, the code itself has got nothing to do with the maximum size of arrays. It's just a claim. – Pacerier Nov 26 '15 at 04:06
  • @JohnWinter, The quote states "Some VMs reserve some header words in an array". So the `-8` is due to the bytes the reserved header words would occupy. – Pacerier Nov 26 '15 at 04:08
  • 1
    @Pacerier 2^31 (Integer.MAX_VALUE - 8, approximate) * 2^2 (assume 4 byte int) = 2 ^ 33. But I think 64-bit system have at least 48 bit for their virtual address space. A portion of virtual address space goes to heap segment, so it seems the array in Java can get much larger than this size. Am I missing anything? – torez233 Aug 11 '22 at 05:05
41

There are actually two limits. One, the maximum element indexable for the array and, two, the amount of memory available to your application. Depending on the amount of memory available and the amount used by other data structures, you may hit the memory limit before you reach the maximum addressable array element.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
31

Going by this article http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays:

Java has been criticized for not supporting arrays of more than 231−1 (about 2.1 billion) elements. This is a limitation of the language; the Java Language Specification, Section 10.4, states that:

Arrays must be indexed by int values... An attempt to access an array component with a long index value results in a compile-time error.

Supporting large arrays would also require changes to the JVM. This limitation manifests itself in areas such as collections being limited to 2 billion elements and the inability to memory map files larger than 2 GiB. Java also lacks true multidimensional arrays (contiguously allocated single blocks of memory accessed by a single indirection), which limits performance for scientific and technical computing.

Nayuki
  • 17,911
  • 6
  • 53
  • 80
working
  • 873
  • 3
  • 11
  • 21
  • 8
    Java lacks the syntactic sugar for multidimensional arrays, but you can still "have" them with a little bit of multiplication (unless the total size of the array exceeded the aforementioned limit) – kbolino Jan 27 '16 at 22:02
  • 2
    @kbolino It's true. I'm sure the scientific users are smart enough to make their own multi-dimensional arrays – Stefan Reich Jul 26 '20 at 11:52
15

Arrays are non-negative integer indexed , so maximum array size you can access would be Integer.MAX_VALUE. The other thing is how big array you can create. It depends on the maximum memory available to your JVM and the content type of the array. Each array element has it's size, example. byte = 1 byte, int = 4 bytes, Object reference = 4 bytes (on a 32 bit system)

So if you have 1 MB memory available on your machine, you could allocate an array of byte[1024 * 1024] or Object[256 * 1024].

Answering your question - You can allocate an array of size (maximum available memory / size of array item).

Summary - Theoretically the maximum size of an array will be Integer.MAX_VALUE. Practically it depends on how much memory your JVM has and how much of that has already been allocated to other objects.

Dhanuka
  • 2,826
  • 5
  • 27
  • 38
4

I tried to create a byte array like this

byte[] bytes = new byte[Integer.MAX_VALUE-x];
System.out.println(bytes.length);

With this run configuration:

-Xms4G -Xmx4G

And java version:

Openjdk version "1.8.0_141"

OpenJDK Runtime Environment (build 1.8.0_141-b16)

OpenJDK 64-Bit Server VM (build 25.141-b16, mixed mode)

It only works for x >= 2 which means the maximum size of an array is Integer.MAX_VALUE-2

Values above that give

Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit at Main.main(Main.java:6)

2

Maximum number of elements of an array is (2^31)−1 or 2 147 483 647

Baby
  • 5,062
  • 3
  • 30
  • 52
  • 6
    Java can't allocate array of size `Integer.MAX_VALUE - 1`, you'll get "java.lang.OutOfMemoryError: Requested array size exceeds VM limit". The maximum number of elements in JDK 6 and above is `Integer.MAX_VALUE - 2` = 2 147 483 645. – Alexey Ivanov Feb 27 '15 at 10:43
0

Yes, there limit on java array. Java uses an integer as an index to the array and the maximum integer store by JVM is 2^32. so you can store 2,147,483,647 elements in the array.

In case you need more than max-length you can use two different arrays but the recommended method is store data into a file. because storing data in the file has no limit. because files stored in your storage drivers but array are stored in JVM. JVM provides limited space for program execution.

-1

Actually it's java limitation caping it at 2^30-4 being 1073741820. Not 2^31-1. Dunno why but i tested it manually on jdk. 2^30-3 still throwing vm except

Edit: fixed -1 to -4, checked on windows jvm

Ferned
  • 11
  • 3
  • 2
    You're using a 32-bit JVM. Use a 64-bit JVM and the JVM limit will be close to 2^31. (You also need heap space available, which is not the default, and will be affected by your physical memory.) – dave_thompson_085 Sep 10 '19 at 20:27
-1

Java array has a limit because its a integer array, what meant it has up to 2,147,483,647 elements in array