2016-02-23 22 views
15

Java'da ArrayList s ürünlerinin nasıl geliştirildiğini okuyarak ilgili belgeleri okuyorum. Neden hugeCapacity(int minCapacity) yönteminin neden Integer.MAX_VALUE veya MAX_ARRAY_SIZE döndürmeyi seçtiğini anlamıyorum. MAX_ARRAY_SIZE sınıfında tanımlanan nasıl kaynaktan Java 8 Arraylist hugeCapacity (int) application

,

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

Bu Integer.MAX_VALUE bir tamsayı (32 bits) büyüklüğüne göre kapalı hariç neredeyse aynıdır.

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 |  } 

herkes ince bir fark MAX_ARRAY_SIZE karşı Integer.MAX_VALUE dönen ne olduğunu bana söyleyebilir misiniz? Her iki şekilde de OutOfMemoryError oluşmamalıdır?

+2

cevap MAX_ARRAY_SIZE yukarıdaki yorumunda hemen orada "sınırlandırır. Anlamı: Bazı VM'lerde OutOfMemory'yi önleyebilirsek, aksi takdirde Integer.MAX_VALUE değerini atarız ve eğer şanslıysanız (VM'ye bağlı olarak) başarılı oluruz. –

cevap

12

Maksimum dizi boyutu, farklı JVM'ler arasında değişen ve genellikle Integer.MAX_VALUE'dan biraz daha az olan bazı sayılarla sınırlıdır. Yani, Integer.MAX_VALUE elemanlarının dizisini ayırmak, bunu yapmak için yeterli belleğiniz olsa bile, JVM'lerin çoğunda OutOfMemoryError olacaktır. MAX_ARRAY_SIZE, mevcut JVM'lerin çoğunda geçerli dizi boyutu olduğunu varsayar. ArrayList boyutu Integer.MAX_VALUE boyutuna yaklaştığında (örneğin, 1_500_000_000 öğesinden daha fazla öğeye sahipseniz ve bir diziyi büyütmeniz gerekiyorsa), bu MAX_ARRAY_SIZE'a büyütüldüğü için, bu işlem başarıyla gerçekleştirilebilir (yeterli belleğe sahip olduğunuz varsayılarak). Yalnızca öğelerin sayısı MAX_ARRAY_SIZE'u aşarsa, ArrayList, Integer.MAX_VALUE öğelerinin bir dizisini ayırmaya çalışır (bu, JVM'lerin çoğunda başarısız olabilir, ancak , bazılarında başarılı olabilir). Bu sayede, hemen hemen her JVM'de MAX_ARRAY_SIZE'a kadar olan öğeleri güvenli bir şekilde ekleyebilir ve bundan sonra sorun yaşayabilirsiniz.

Oracle'ın uygulama aşamalarından
2

(Java 8 güncellemesi 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; 

Onlar dönmek   (2 - 1) - 8   diğeri tarafından çalıştırıldığında kendi kod OutOfMemoryError oluşturmaz emin olmak için VM uygulaması. "dizinin maksimum boyutu ayırmaya dizideki bazı başlık kelimeler OutOfMemoryError sonuçlanabilir büyük diziler tahsis etme girişimleri Bazı VM'lerin rezervi:.:. Talep edilen dizi boyutunda VM aşıyor