2016-02-23 14 views
15

Czytam dokumentację dotyczącą sposobu, w jaki są rozwijane ArrayList w Javie. Nie rozumiem, dlaczego metoda hugeCapacity(int minCapacity) decyduje się na zwrot: Integer.MAX_VALUE lub MAX_ARRAY_SIZE.Java 8 Arraylist Implementacja hugeCapacity (int)

Od jak MAX_ARRAY_SIZE jest zdefiniowana w klasie

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

To prawie taka sama jak Integer.MAX_VALUE except poza wielkością jednej liczby całkowitej (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 |  } 

Czy ktoś może mi powiedzieć, co jest subtelna różnica w powrocie Integer.MAX_VALUE porównaniu MAX_ARRAY_SIZE? Tak czy inaczej, czy nie powinien wystąpić błąd?

+2

Odpowiedź jest tam w komentarzu powyżej MAX_ARRAY_SIZE: „Maksymalny rozmiar tablicy do przeznaczenia części maszyn wirtualnych rezerwę niektóre nagłówka słowa tablicy próbuje przydzielić większe tablice mogą spowodować OutOfMemoryError:.. Zamówiony rozmiar tablicy przekracza VM limit". Czyli: jeśli uda nam się uniknąć OutOfMemory na niektórych maszynach wirtualnych, w przeciwnym razie przydzielimy Integer.MAX_VALUE i odniesiemy sukces, jeśli będziecie mieli szczęście (w zależności od VM) –

Odpowiedz

12

Maksymalny rozmiar tablicy jest ograniczony do pewnej liczby, która zmienia się w różnych maszynach JVM i zwykle jest nieco mniejsza niż Integer.MAX_VALUE. W ten sposób przydzielanie tablicy elementów Integer.MAX_VALUE będzie mieć OutOfMemoryError na większości maszyn JVM, nawet jeśli masz wystarczającą ilość pamięci, aby to zrobić. MAX_ARRAY_SIZE zakłada poprawny rozmiar tablicy dla większości istniejących maszyn JVM. Kiedy rozmiar ArrayList zbliża się do Integer.MAX_VALUE (na przykład masz więcej niż 1_500_000_000 elementów i potrzebujesz powiększyć tablicę), jest on powiększany do tego MAX_ARRAY_SIZE, więc może być z powodzeniem wykonany (zakładając, że masz wystarczającą ilość pamięci). Tylko jeśli liczba elementów przekracza MAX_ARRAY_SIZE, ArrayList próbuje przydzielić tablicę elementów Integer.MAX_VALUE (które prawdopodobnie zawiodą w większości maszyn JVM, ale na niektórych z nich może się powieść po osiągnięciu wartości). W ten sposób możesz bezpiecznie dodawać elementy do MAX_ARRAY_SIZE na prawie każdej maszynie JVM i dopiero wtedy będą miały problemy.

2

Od wdrożenia Oracle (Java 8 Aktualizacja 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; 

Wracają   (2 - 1) - 8  , aby upewnić się, że ich kod nie tworzyć OutOfMemoryError gdy są wykonywane przez inny Implementacja VM.