Java 8 Arraylist hugeCapacity(int) implementation

丶灬走出姿态 提交于 2020-01-01 08:20:47

问题


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/35582809/java-8-arraylist-hugecapacityint-implementation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!