Y a-t-il une limite au nombre d'éléments qu'un tableau Java peut contenir? Si oui, c'est quoi?
Y a-t-il une limite au nombre d'éléments qu'un tableau Java peut contenir? Si oui, c'est quoi?
Réponses:
Je n'ai pas vu la bonne réponse, même si c'est très facile à tester.
Dans une machine virtuelle HotSpot récente, la bonne réponse est Integer.MAX_VALUE - 5
. Une fois que vous allez au-delà de cela:
public class Foo {
public static void main(String[] args) {
Object[] array = new Object[Integer.MAX_VALUE - 4];
}
}
Vous obtenez:
Exception in thread "main" java.lang.OutOfMemoryError:
Requested array size exceeds VM limit
MAX_VALUE-2
éléments. Ceci est indépendant de ce que j'alloue, et je me demande vraiment à quoi la machine virtuelle peut-elle utiliser les deux "choses" (la longueur ne tient pas sur 2 octets).
Integer.MAX_VALUE+1
, vous aurez un débordement d'entier. Les tailles de tableau en Java ne le sont int
pas long
; quel que soit le type de données que vous stockez dans votre tableau, octets ou références. Les chaînes ne sont que des références d'objet.
Integer.MAX_VALUE - 2
= 2 147 483 645. Java alloue correctement un tel tableau si vous l'exécutez avec -Xmx13G
. Il échoue OutOfMemoryError: Java heap space
si vous réussissez -Xmx12G
.
Ceci est (bien sûr) totalement dépendant de la machine virtuelle.
En parcourant le code source de OpenJDK 7 et 8 java.util.ArrayList
, .Hashtable
, .AbstractCollection
, .PriorityQueue
et .Vector
, vous pouvez voir cette réclamation se répète:
/** * 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;
qui est ajouté par Martin Buchholz (Google) le 2010-05-09 ; révisé par Chris Hegarty (Oracle).
Donc, nous pouvons probablement dire que le nombre maximum "sûr" serait de 2 147 483 639 ( Integer.MAX_VALUE - 8
) et "les tentatives d'allocation de tableaux plus grands peuvent entraîner OutOfMemoryError ".
(Oui, la revendication autonome de Buchholz n'inclut pas de preuves à l'appui, il s'agit donc d'un appel calculé à l'autorité. Même au sein d'OpenJDK lui-même, nous pouvons voir du code comme celui return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
qui montre que cela MAX_ARRAY_SIZE
n'a pas encore une réelle utilité.)
-8
?
-8
c'est dû aux octets que les mots d'en-tête réservés occuperaient.
Il y a en fait deux limites. Un, l'élément maximum indexable pour le tableau et, deux, la quantité de mémoire disponible pour votre application. Selon la quantité de mémoire disponible et la quantité utilisée par d'autres structures de données, vous pouvez atteindre la limite de mémoire avant d'atteindre l'élément de tableau adressable maximum.
En passant par cet article http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays :
Java a été critiqué pour ne pas prendre en charge les tableaux de plus de 2 31 −1 (environ 2,1 milliards) d'éléments. Il s'agit d'une limitation de la langue; la spécification du langage Java, section 10.4, stipule que:
Les tableaux doivent être indexés par des valeurs int ... Une tentative d'accès à un composant de tableau avec une valeur d'index longue entraîne une erreur de compilation.
La prise en charge de baies de grande taille nécessiterait également des modifications de la JVM. Cette limitation se manifeste dans des domaines tels que les collections limitées à 2 milliards d'éléments et l'impossibilité de stocker des fichiers de mappage supérieurs à 2 Gio. Java manque également de véritables tableaux multidimensionnels (blocs de mémoire alloués de manière contiguë accédés par une seule indirection), ce qui limite les performances de l'informatique scientifique et technique.
Les tableaux sont indexés sur des nombres entiers non négatifs, donc la taille maximale du tableau à laquelle vous pouvez accéder serait Integer.MAX_VALUE
. L'autre chose est la taille du tableau que vous pouvez créer. Cela dépend de la mémoire maximale disponible pour votre JVM
et du type de contenu de la baie. Chaque élément du tableau a sa taille, par exemple. byte = 1 byte
, int = 4 bytes
,Object reference = 4 bytes (on a 32 bit system)
Donc, si vous avez de la 1 MB
mémoire disponible sur votre machine, vous pouvez allouer un tableau de byte[1024 * 1024]
ouObject[256 * 1024]
.
Répondre à votre question - Vous pouvez allouer un tableau de taille (mémoire maximale disponible / taille de l'élément de tableau).
Résumé - Théoriquement, la taille maximale d'un tableau sera Integer.MAX_VALUE
. Cela dépend pratiquement de la quantité de mémoire dont vous disposez JVM
et de celle qui a déjà été allouée à d'autres objets.
J'ai essayé de créer un tableau d'octets comme celui-ci
byte[] bytes = new byte[Integer.MAX_VALUE-x];
System.out.println(bytes.length);
Avec cette configuration d'exécution:
-Xms4G -Xmx4G
Et la version java:
Version Openjdk "1.8.0_141"
Environnement d'exécution OpenJDK (build 1.8.0_141-b16)
VM serveur OpenJDK 64 bits (build 25.141-b16, mode mixte)
Cela ne fonctionne que pour x> = 2, ce qui signifie que la taille maximale d'un tableau est Integer.MAX_VALUE-2
Des valeurs au-dessus qui donnent
Exception dans le thread "principal" java.lang.OutOfMemoryError: la taille de tableau demandée dépasse la limite de machine virtuelle sur Main.main (Main.java:6)
Oui, il y a une limite sur le tableau java. Java utilise un entier comme index du tableau et le magasin d'entiers maximum par JVM est 2 ^ 32. vous pouvez donc stocker 2 147 483 647 éléments dans le tableau.
Si vous avez besoin de plus que la longueur maximale, vous pouvez utiliser deux tableaux différents, mais la méthode recommandée consiste à stocker les données dans un fichier. car le stockage des données dans le fichier n'a pas de limite. car les fichiers stockés dans vos pilotes de stockage mais la baie sont stockés dans JVM. JVM offre un espace limité pour l'exécution du programme.
Nombre maximal d'éléments d'un array
est (2^31)−1
ou2 147 483 647
Integer.MAX_VALUE - 1
, vous obtiendrez "java.lang.OutOfMemoryError: la taille du tableau demandée dépasse la limite de la machine virtuelle". Le nombre maximum d'éléments dans JDK 6 et au-dessus est Integer.MAX_VALUE - 2
= 2 147 483 645.
En fait, c'est la limitation java qui la limite à 2 ^ 30-4 étant 1073741820. Pas 2 ^ 31-1. Je ne sais pas pourquoi mais je l'ai testé manuellement sur jdk.2 ^ 30-3 jetant toujours vm sauf
Edit: fixe -1 à -4, vérifié sur windows jvm