Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Arraylist hugeCapacity(int) implementation

Tags:

java

arraylist

I'm reading the documentation for how ArrayLists in Java are grown. I don't understand why the hugeCapacity(int minCapacity) method chooses to return either Integer.MAX_VALUE or MAX_ARRAY_SIZE.

From how MAX_ARRAY_SIZE is defined in the class,

244 |     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

It's almost the same as Integer.MAX_VALUE except off by the size of one integer (32 bits).

264 |     private static int hugeCapacity(int minCapacity) {
265 |         if (minCapacity < 0) // overflow
266 |             throw new OutOfMemoryError();
267 |         return (minCapacity > MAX_ARRAY_SIZE) ?
268 |             Integer.MAX_VALUE :
269 |             MAX_ARRAY_SIZE;
270 |     }

Can anyone tell me what the subtle difference is in returning Integer.MAX_VALUE versus MAX_ARRAY_SIZE? Either way, shouldn't an OutOfMemoryError occur?

like image 428
Hen Avatar asked Feb 23 '16 16:02

Hen


People also ask

How is ArrayList implemented in Java?

ArrayList uses an Object class array to store the objects. By default, ArrayList creates an array of size 10. While initializing the Array, we can specify the size of Array. When adding or removing elements, the space in the Array will automatically be adjusted.

Does ArrayList implement collection?

ArrayList in Java is used to store dynamically sized collection of elements. Contrary to Arrays that are fixed in size, an ArrayList grows its size automatically when new elements are added to it. ArrayList is part of Java's collection framework and implements Java's List interface.

How does the size of ArrayList increases dynamically?

The ArrayList size increases dynamically because whenever the ArrayList class requires to resize then it will create a new array of bigger size and copies all the elements from the old array to the new array.

How does ArrayList grow internally?

Internally an ArrayList uses an Object[] . As you add items to an ArrayList , the list checks to see if the backing array has room left. If there is room, the new item is just added at the next empty space. If there is not room, a new, larger, array is created, and the old array is copied into the new one.

What is ensurecapacity in ArrayList in Java?

ArrayList ensureCapacity() method in Java with Examples. The ensureCapacity() method of java.util.ArrayList class increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument. Syntax:

What is the default capacity of ArrayList in Java?

ArrayList is a resizable array implementation in java. When creating an ArrayList you can provide initial capacity then the array is declared with the given capacity. The default capacity value is 10. If the initial capacity is not specified by the user then the default capacity is used to create an array of objects.

How to increase the size of an ArrayList in Java?

The grow method in the ArrayList class gives the new size array. In Java 8 and later The new capacity is calculated which is 50% more than the old capacity and the array is increased by that capacity. It uses Arrays.copyOf which gives the array increased to the new length by right shift operator also it will grow by 50% of old capacity.

What happens when ArrayList capacity is exhausted?

If you see the ArrayList internal implementation in Java, everytime add () method is called it is ensured that ArrayList has required capacity. If the capacity is exhausted a new array is created with 50% more capacity than the previous one. All the elements are also copied from previous array to new array.


2 Answers

The maximal array size is limited to some number which varies across different JVMs and usually is slightly less than Integer.MAX_VALUE. So allocating the array of Integer.MAX_VALUE elements you will have OutOfMemoryError on most of JVMs even if you have enough memory to do it. MAX_ARRAY_SIZE assumes to be valid array size on the most of existing JVMs. So when ArrayList size approaches to Integer.MAX_VALUE (for example, you have more than 1_500_000_000 elements and need to enlarge an array), it's enlarged to this MAX_ARRAY_SIZE, so it can be successfully performed (assuming you have enough memory). Only if number of elements exceeds MAX_ARRAY_SIZE, the ArrayList tries to allocate an array of Integer.MAX_VALUE elements (which will likely to fail on most of JVMs, but may succeed on some of them). This way you can safely add elements up to MAX_ARRAY_SIZE on almost any JVM and only after that will have problems.

like image 115
Tagir Valeev Avatar answered Sep 19 '22 17:09

Tagir Valeev


From Oracle's implementation (Java 8 update 31):

/**
 * The maximum size of array to allocate.
 * 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;

They return   (2 31 - 1) - 8   to make sure their code do not create OutOfMemoryError when executed by another VM implementation.

like image 38
Laf Avatar answered Sep 19 '22 17:09

Laf