2016-02-23 5 views
15

Sto leggendo la documentazione su come vengono sviluppati i ArrayList s in Java. Non capisco perché il metodo hugeCapacity(int minCapacity) scelga di restituire Integer.MAX_VALUE o MAX_ARRAY_SIZE.Java 8 Arraylist implementazione enormeCapacity (int)

Da come MAX_ARRAY_SIZE è definito nella classe,

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

È quasi uguale Integer.MAX_VALUE tranne fuori dalle dimensioni di un intero (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 |  } 

Qualcuno può dirmi che cosa la sottile differenza è nel ritorno contro Integer.MAX_VALUEMAX_ARRAY_SIZE? In entrambi i casi, non dovrebbe verificarsi un OutOfMemoryError?

+2

La risposta è proprio lì nel commento sopra MAX_ARRAY_SIZE: "La dimensione massima dell'array da allocare Alcuni riserva VM alcuni parole intestazione in un array tenta di allocare matrici più grandi possono provocare OutOfMemoryError:.. Dimensione dell'array richiesta oltrepassa VM limite". Significato: Se possiamo evitare OutOfMemory su alcune macchine virtuali, altrimenti assegneremo Integer.MAX_VALUE e riusciremo se sarai fortunato (a seconda della VM) –

risposta

12

La dimensione massima dell'array è limitata a un numero che varia tra diverse JVM e di solito è leggermente inferiore a Integer.MAX_VALUE. Quindi, assegnando la serie di elementi Integer.MAX_VALUE, avrai OutOfMemoryError sulla maggior parte delle JVM anche se hai abbastanza memoria per farlo. MAX_ARRAY_SIZE assume dimensioni di array valide sulla maggior parte delle JVM esistenti. Pertanto, quando la dimensione ArrayList si avvicina a Integer.MAX_VALUE (ad esempio, sono presenti più di 1_500_000_000 elementi e occorre ingrandire un array), viene ingrandita fino a questo MAX_ARRAY_SIZE, in modo che possa essere eseguita correttamente (presupponendo che si disponga di memoria sufficiente). Solo se il numero di elementi supera MAX_ARRAY_SIZE, il ArrayList tenta di allocare un array di elementi Integer.MAX_VALUE (che probabilmente non funzionerà sulla maggior parte delle JVM, ma potrebbe avere su alcuni di essi). In questo modo puoi tranquillamente aggiungere elementi fino a MAX_ARRAY_SIZE su quasi tutte le JVM e solo dopo avremo problemi.

2

Da implementazione di Oracle (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; 

Tornano   (2 - 1) - 8   per assicurarsi che il loro codice non creano OutOfMemoryError quando viene eseguito da un altro Implementazione VM.