Gibt es eine Begrenzung für die Anzahl der Elemente, die ein Java-Array enthalten kann? Wenn ja, was ist das?
Gibt es eine Begrenzung für die Anzahl der Elemente, die ein Java-Array enthalten kann? Wenn ja, was ist das?
Antworten:
Ich habe nicht die richtige Antwort gesehen, obwohl es sehr einfach zu testen ist.
In einer aktuellen HotSpot-VM lautet die richtige Antwort Integer.MAX_VALUE - 5
. Sobald Sie darüber hinausgehen:
public class Foo {
public static void main(String[] args) {
Object[] array = new Object[Integer.MAX_VALUE - 4];
}
}
Du erhältst:
Exception in thread "main" java.lang.OutOfMemoryError:
Requested array size exceeds VM limit
MAX_VALUE-2
Elemente zuordnen . Dies ist unabhängig von dem, was ich zuordne, und ich frage mich wirklich, wofür die VM die beiden "Dinge" verwenden kann (die Länge passt nicht in 2 Bytes).
Integer.MAX_VALUE+1
, Sie werden einen ganzzahligen Überlauf haben. Array-Größen in Java sind int
nicht long
; Unabhängig davon, welchen Datentyp Sie in Ihrem Array, Ihren Bytes oder Referenzen speichern. Zeichenfolgen sind nur Objektreferenzen.
Integer.MAX_VALUE - 2
= 2 147 483 645. Java weist ein solches Array erfolgreich zu, wenn Sie es mit ausführen -Xmx13G
. Es schlägt fehl, OutOfMemoryError: Java heap space
wenn Sie bestehen -Xmx12G
.
Dies ist (natürlich) vollständig VM-abhängig.
Browsing durch den Quellcode von OpenJDK 7 und 8 java.util.ArrayList
, .Hashtable
, .AbstractCollection
, .PriorityQueue
, und .Vector
können Sie sehen , diese Forderung wiederholt werden:
/** * 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;
welches von Martin Buchholz (Google) am 09.05.2010 hinzugefügt wird ; rezensiert von Chris Hegarty (Oracle).
Daher können wir wahrscheinlich sagen, dass die maximale "sichere" Anzahl 2 147 483 639 ( Integer.MAX_VALUE - 8
) beträgt und "Versuche, größere Arrays zuzuweisen, zu OutOfMemoryError führen können ".
(Ja, Buchholz 'eigenständige Behauptung enthält keine Belege, daher handelt es sich um einen kalkulierten Aufruf an die Behörde. Selbst innerhalb von OpenJDK selbst können wir Code sehen, return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
der zeigt, dass er MAX_ARRAY_SIZE
noch keinen wirklichen Nutzen hat.)
-8
?
-8
liegt also an den Bytes, die die reservierten Header-Wörter belegen würden.
Es gibt tatsächlich zwei Grenzen. Erstens das maximale für das Array indizierbare Element und zweitens die für Ihre Anwendung verfügbare Speichermenge. Abhängig von der verfügbaren Speichermenge und der von anderen Datenstrukturen verwendeten Speichermenge können Sie die Speichergrenze erreichen, bevor Sie das maximal adressierbare Array-Element erreichen.
Gehen Sie diesen Artikel durch http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays :
Java wurde dafür kritisiert, dass es keine Arrays mit mehr als 2 31 -1 (ungefähr 2,1 Milliarden) Elementen unterstützt. Dies ist eine Einschränkung der Sprache; In der Java-Sprachspezifikation, Abschnitt 10.4, heißt es:
Arrays müssen durch int-Werte indiziert werden ... Ein Versuch, auf eine Array-Komponente mit einem langen Indexwert zuzugreifen, führt zu einem Fehler bei der Kompilierung.
Die Unterstützung großer Arrays würde auch Änderungen an der JVM erfordern. Diese Einschränkung äußert sich in Bereichen wie der Beschränkung von Sammlungen auf 2 Milliarden Elemente und der Unfähigkeit, Speicherzuordnungsdateien mit mehr als 2 GiB zu speichern. Java fehlen auch echte mehrdimensionale Arrays (zusammenhängend zugewiesene einzelne Speicherblöcke, auf die durch eine einzelne Indirektion zugegriffen wird), was die Leistung für wissenschaftliches und technisches Rechnen einschränkt.
Arrays sind nicht negativ ganzzahlig indiziert, sodass Sie maximal auf die Arraygröße zugreifen können Integer.MAX_VALUE
. Die andere Sache ist, wie großes Array Sie erstellen können. Dies hängt vom maximal verfügbaren Speicher JVM
und dem Inhaltstyp des Arrays ab. Jedes Array-Element hat beispielsweise seine Größe. byte = 1 byte
, int = 4 bytes
,Object reference = 4 bytes (on a 32 bit system)
Wenn 1 MB
auf Ihrem Computer also Speicher verfügbar ist, können Sie ein Array von byte[1024 * 1024]
oder zuweisen Object[256 * 1024]
.
Beantwortung Ihrer Frage - Sie können ein Array mit einer Größe zuweisen (maximal verfügbarer Speicher / Größe des Array-Elements).
Zusammenfassung - Theoretisch ist die maximale Größe eines Arrays Integer.MAX_VALUE
. Praktisch hängt es davon ab, wie viel Speicher Sie JVM
haben und wie viel davon bereits anderen Objekten zugewiesen wurde.
Ich habe versucht, ein solches Byte-Array zu erstellen
byte[] bytes = new byte[Integer.MAX_VALUE-x];
System.out.println(bytes.length);
Mit dieser Laufkonfiguration:
-Xms4G -Xmx4G
Und Java-Version:
Openjdk-Version "1.8.0_141"
OpenJDK-Laufzeitumgebung (Build 1.8.0_141-b16)
OpenJDK 64-Bit-Server-VM (Build 25.141-b16, gemischter Modus)
Es funktioniert nur für x> = 2, was bedeutet, dass die maximale Größe eines Arrays Integer.MAX_VALUE-2 ist
Werte darüber geben
Ausnahme im Thread "main" java.lang.OutOfMemoryError: Die angeforderte Arraygröße überschreitet das VM-Limit bei Main.main (Main.java:6).
Ja, das Java-Array ist begrenzt. Java verwendet eine Ganzzahl als Index für das Array und der maximale Ganzzahlspeicher von JVM beträgt 2 ^ 32. Sie können also 2.147.483.647 Elemente im Array speichern.
Wenn Sie mehr als die maximale Länge benötigen, können Sie zwei verschiedene Arrays verwenden. Die empfohlene Methode besteht jedoch darin, Daten in einer Datei zu speichern. weil das Speichern von Daten in der Datei keine Begrenzung hat. weil Dateien, die in Ihren Speichertreibern, aber im Array gespeichert sind, in JVM gespeichert sind. JVM bietet begrenzten Speicherplatz für die Programmausführung.
Maximale Anzahl von Elementen eines array
ist (2^31)−1
oder2 147 483 647
Integer.MAX_VALUE - 1
. Sie erhalten "java.lang.OutOfMemoryError: Angeforderte Arraygröße überschreitet VM-Grenze". Die maximale Anzahl von Elementen in JDK 6 und höher ist Integer.MAX_VALUE - 2
= 2 147 483 645.
Tatsächlich ist es eine Java-Beschränkung, die es auf 2 ^ 30-4 begrenzt und 1073741820 ist. Nicht 2 ^ 31-1. Keine Ahnung warum, aber ich habe es manuell auf JDK getestet. 2 ^ 30-3 wirft immer noch vm außer
Bearbeiten: -1 bis -4 behoben, unter Windows JVM aktiviert