Apakah array Java memiliki ukuran maksimum?

214

Apakah ada batasan jumlah elemen yang bisa diisi oleh array Java? Jika demikian, apakah itu?

Kadal
sumber
5
Anda menerima jawaban yang salah, coba alokasikan array yang begitu panjang (dan tidak, saya tidak kehabisan memori).
maaartinus
Terkait erat: stackoverflow.com/questions/878309/…
Ciro Santilli 郝海东 冠状 病 六四 六四 事件 法轮功
Jawaban yang tepat adalah stackoverflow.com/questions/31382531/…
Ivan Mamontov

Jawaban:

184

Belum melihat jawaban yang benar, meskipun sangat mudah untuk diuji.

Dalam HotSpot VM baru-baru ini, jawaban yang benar adalah Integer.MAX_VALUE - 5. Setelah Anda melampaui itu:

public class Foo {
  public static void main(String[] args) {
    Object[] array = new Object[Integer.MAX_VALUE - 4];
  }
}

Anda mendapatkan:

Exception in thread "main" java.lang.OutOfMemoryError:
  Requested array size exceeds VM limit
Kevin Bourrillion
sumber
57
Saya pikir ide tentang downvotes tidak masuk akal kecuali kita bersedia untuk downvote jawaban yang jelas dan salah . Apakah perbedaan lima byte benar-benar penting di dunia nyata, TIDAK, tentu saja tidak. Tetapi saya khawatir bahwa orang-orang bersedia memberikan jawaban "secara otoritatif" tanpa mencoba untuk melihat apakah itu benar-benar berfungsi. Adapun batas memori, well, DUH. Itu seperti jika Anda bertanya kepada saya "berapa banyak anggur yang bisa Anda makan?" dan saya berkata, "Yah, itu tergantung pada berapa banyak yang saya miliki di lemari es pada saat itu."
Kevin Bourrillion
7
Apakah Anda tahu mengapa itu tidak memberi Anda lima byte? Apakah ini selalu sesuatu yang selalu terjadi di Jawa, atau mungkinkah itu hanya terkait dengan memori komputer Anda atau sesuatu?
Taymon
17
@ Kevin Bourrillion: Ini tampaknya telah berubah, menggunakan Oracle 1.7.0_07 Saya dapat mengalokasikan hingga MAX_VALUE-2elemen. Ini independen dari apa yang saya alokasikan, dan saya benar-benar bertanya-tanya untuk apa VM dapat menggunakan dua "hal" untuk (panjangnya tidak muat dalam 2 byte).
maaartinus
3
@ TomášZato paling lambat pada Integer.MAX_VALUE+1, Anda akan memiliki integer overflow. Ukuran array di Jawa inttidak long; tidak peduli apa tipe data yang Anda simpan dalam array, byte atau referensi Anda. String hanyalah referensi Objek.
Memiliki QUIT - Anony-Mousse
8
Jumlah maksimum elemen dalam array di JDK 6 dan di atas adalah Integer.MAX_VALUE - 22 147 483 645. Java berhasil mengalokasikan array seperti itu jika Anda menjalankannya -Xmx13G. Gagal dengan OutOfMemoryError: Java heap spacejika Anda lulus -Xmx12G.
Alexey Ivanov
127

Ini (tentu saja) benar-benar tergantung pada VM.

Browsing melalui kode sumber dari OpenJDK 7 dan 8 java.util.ArrayList, .Hashtable, .AbstractCollection, .PriorityQueue, dan .Vector, Anda dapat melihat ini klaim sedang berulang:

/**
 * 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;

yang ditambahkan oleh Martin Buchholz (Google) pada 2010-05-09 ; diulas oleh Chris Hegarty (Oracle).

Jadi, mungkin kita dapat mengatakan bahwa jumlah "aman" maksimum adalah 2 147 483 639 ( Integer.MAX_VALUE - 8) dan "upaya untuk mengalokasikan array yang lebih besar dapat menghasilkan OutOfMemoryError ".

(Ya, klaim mandiri Buchholz tidak termasuk bukti pendukung, jadi ini adalah banding yang diperhitungkan kepada otoritas. Bahkan di dalam OpenJDK sendiri, kita dapat melihat kode seperti return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;yang menunjukkan bahwa MAX_ARRAY_SIZEbelum ada penggunaan yang nyata .)

Pacerier
sumber
Dan mengapa kita perlu menambahkan -8?
JohnWinter
@Pacerier. Tidakkah MAX_ARRAY_SIZE ini diterapkan hanya ketika Anda menggunakan ArrayList? Itu berbeda dari menggunakan array seperti int [] array = new int [some_value_here]; bukan? Mengapa konstanta yang didefinisikan dalam ArrayList dapat diterapkan ke array normal (didefinisikan dengan [])? Apakah mereka sama di belakang layar?
Tiago
1
@ Tiago, Tidak, kode itu sendiri tidak ada hubungannya dengan ukuran maksimum array. Itu hanya klaim.
Pacerier
@JohnWinter, Kutipan menyatakan "Beberapa VM memesan beberapa kata header dalam array". Jadi -8karena byte kata-kata header yang dicadangkan akan menempati.
Pacerier
38

Sebenarnya ada dua batasan. Satu, elemen maksimum yang dapat diindeks untuk array dan, dua, jumlah memori yang tersedia untuk aplikasi Anda. Bergantung pada jumlah memori yang tersedia dan jumlah yang digunakan oleh struktur data lain, Anda dapat mencapai batas memori sebelum Anda mencapai elemen array yang dapat dialamatkan maksimum.

tvanfosson
sumber
27

Pergi dengan artikel ini http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays :

Java telah dikritik karena tidak mendukung array lebih dari 2 31 −1 (sekitar 2,1 miliar) elemen. Ini adalah batasan bahasa; Spesifikasi Bahasa Jawa, Bagian 10.4, menyatakan bahwa:

Array harus diindeks oleh nilai int ... Upaya untuk mengakses komponen array dengan nilai indeks yang panjang menghasilkan kesalahan waktu kompilasi.

Mendukung array besar juga akan memerlukan perubahan pada JVM. Keterbatasan ini memanifestasikan dirinya di bidang-bidang seperti koleksi terbatas pada 2 miliar elemen dan ketidakmampuan untuk file peta memori yang lebih besar dari 2 GiB. Java juga tidak memiliki array multidimensi yang sebenarnya (secara bersamaan dialokasikan blok memori tunggal yang diakses oleh satu tipuan), yang membatasi kinerja untuk komputasi ilmiah dan teknis.

kerja
sumber
6
Java tidak memiliki gula sintaksis untuk array multidimensi, tetapi Anda masih bisa "memilikinya" dengan sedikit penggandaan (kecuali ukuran total array melebihi batas yang disebutkan di atas)
kbolino
11

Array adalah bilangan bulat non-negatif yang diindeks, jadi ukuran array maksimum yang dapat Anda akses akan menjadi Integer.MAX_VALUE. Hal lain adalah seberapa besar array yang bisa Anda buat. Itu tergantung pada memori maksimum yang tersedia untuk Anda JVMdan jenis konten array. Setiap elemen array memiliki ukurannya, contoh. byte = 1 byte, int = 4 bytes,Object reference = 4 bytes (on a 32 bit system)

Jadi jika Anda memiliki 1 MBmemori yang tersedia di mesin Anda, Anda dapat mengalokasikan array byte[1024 * 1024]atau Object[256 * 1024].

Menjawab pertanyaan Anda - Anda dapat mengalokasikan ukuran array (memori maksimum yang tersedia / ukuran item array).

Ringkasan - Secara teoritis ukuran maksimum array adalah Integer.MAX_VALUE. Secara praktis itu tergantung pada berapa banyak memori yang Anda JVMmiliki dan berapa banyak yang telah dialokasikan untuk objek lain.

Dhanuka
sumber
3

Saya mencoba membuat array byte seperti ini

byte[] bytes = new byte[Integer.MAX_VALUE-x];
System.out.println(bytes.length);

Dengan konfigurasi run ini:

-Xms4G -Xmx4G

Dan versi java:

Versi Openjdk "1.8.0_141"

OpenJDK Runtime Environment (build 1.8.0_141-b16)

OpenJDK 64-Bit Server VM (build 25.141-b16, mode campuran)

Ini hanya berfungsi untuk x> = 2 yang berarti ukuran maksimum array adalah Integer.MAX_VALUE-2

Nilai di atas memberi itu

Pengecualian di utas "main" java.lang.OutOfMemoryError: Ukuran array yang diminta melebihi batas VM di Main.main (Main.java:6)

Vasilis Nicolaou
sumber
2

Ya, ada batasan pada array java. Java menggunakan integer sebagai indeks ke array dan toko integer maksimum oleh JVM adalah 2 ^ 32. sehingga Anda dapat menyimpan 2.147.483.647 elemen dalam array.

Jika Anda membutuhkan lebih dari panjang maksimal, Anda dapat menggunakan dua array berbeda tetapi metode yang disarankan adalah menyimpan data ke dalam file. karena menyimpan data dalam file tidak memiliki batas. karena file yang disimpan di driver penyimpanan Anda tetapi array disimpan di JVM. JVM menyediakan ruang terbatas untuk eksekusi program.

Avinash Barde
sumber
1

Jumlah maksimum elemen arrayis (2^31)−1atau2 147 483 647

Bayi
sumber
5
Java tidak dapat mengalokasikan ukuran array Integer.MAX_VALUE - 1, Anda akan mendapatkan "java.lang.OutOfMemoryError: Ukuran array yang diminta melebihi batas VM". Jumlah maksimum elemen dalam JDK 6 dan di atas adalah Integer.MAX_VALUE - 2= 2 147 483 645.
Alexey Ivanov
0

Sebenarnya ini pembatasan java caping di 2 ^ 30-4 menjadi 1073741820. Tidak 2 ^ 31-1. Entah mengapa tetapi saya mengujinya secara manual di jdk. 2 ^ 30-3 masih melempar vm kecuali

Sunting: diperbaiki -1 hingga -4, diperiksa pada windows jvm

Basi
sumber
Anda menggunakan JVM 32-bit. Gunakan JVM 64-bit dan batas JVM akan mendekati 2 ^ 31. (Anda juga perlu tumpukan ruang yang tersedia, yang bukan default, dan akan dipengaruhi oleh memori fisik Anda.)
dave_thompson_085