¿Existe un límite para la cantidad de elementos que puede contener una matriz Java? Si es así, ¿qué es?
¿Existe un límite para la cantidad de elementos que puede contener una matriz Java? Si es así, ¿qué es?
Respuestas:
No he visto la respuesta correcta, aunque es muy fácil de probar.
En una VM HotSpot reciente, la respuesta correcta es Integer.MAX_VALUE - 5
. Una vez que vayas más allá de eso:
public class Foo {
public static void main(String[] args) {
Object[] array = new Object[Integer.MAX_VALUE - 4];
}
}
Usted obtiene:
Exception in thread "main" java.lang.OutOfMemoryError:
Requested array size exceeds VM limit
MAX_VALUE-2
elementos. Esto es independiente de lo que asigno, y realmente me pregunto para qué puede usar la VM las dos "cosas" (la longitud no cabe en 2 bytes).
Integer.MAX_VALUE+1
, tendrá un desbordamiento de enteros. Los tamaños de matriz en Java son int
, no long
; no importa qué tipo de datos almacene en su matriz, bytes o referencias. Las cadenas son solo referencias de objetos.
Integer.MAX_VALUE - 2
= 2 147 483 645. Java asigna con éxito dicha matriz si la ejecuta -Xmx13G
. Falla OutOfMemoryError: Java heap space
si pasas -Xmx12G
.
Esto es (por supuesto) totalmente dependiente de VM.
La navegación por el código fuente de OpenJDK 7 y 8 java.util.ArrayList
, .Hashtable
, .AbstractCollection
, .PriorityQueue
, y .Vector
, se puede ver esta afirmación se repite:
/** * 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;
que fue agregado por Martin Buchholz (Google) el 2010-05-09 ; revisado por Chris Hegarty (Oracle).
Entonces, probablemente podemos decir que el número "seguro" máximo sería 2 147 483 639 ( Integer.MAX_VALUE - 8
) y "los intentos de asignar matrices más grandes pueden resultar en OutOfMemoryError ".
(Sí, el reclamo independiente de Buchholz no incluye evidencia de respaldo, por lo que esta es una apelación calculada a la autoridad. Incluso dentro de OpenJDK, podemos ver un código como el return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
que muestra que MAX_ARRAY_SIZE
aún no tiene un uso real ).
-8
?
-8
se debe a los bytes que ocuparían las palabras de encabezado reservadas.
En realidad hay dos límites. Uno, el elemento máximo indexable para la matriz y, dos, la cantidad de memoria disponible para su aplicación. Dependiendo de la cantidad de memoria disponible y la cantidad utilizada por otras estructuras de datos, puede alcanzar el límite de memoria antes de alcanzar el elemento de matriz máximo direccionable.
Pasando por este artículo http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays :
Java ha sido criticado por no admitir matrices de más de 2 31 −1 (aproximadamente 2,1 mil millones) de elementos. Esta es una limitación del idioma; La Especificación del lenguaje Java, Sección 10.4, establece que:
Las matrices deben estar indexadas por valores int ... Un intento de acceder a un componente de matriz con un valor de índice largo da como resultado un error en tiempo de compilación.
El soporte de matrices grandes también requeriría cambios en la JVM. Esta limitación se manifiesta en áreas tales como las colecciones que se limitan a 2 mil millones de elementos y la incapacidad de memoria para asignar archivos de más de 2 GiB. Java también carece de matrices multidimensionales verdaderas (bloques individuales de memoria asignados de forma contigua a los que se accede mediante una sola indirección), lo que limita el rendimiento de la informática científica y técnica.
Las matrices son números enteros no negativos indexados, por lo que el tamaño máximo de matriz a la que puede acceder sería Integer.MAX_VALUE
. La otra cosa es la gran variedad que puede crear. Depende de la memoria máxima disponible para usted JVM
y del tipo de contenido de la matriz. Cada elemento de la matriz tiene su tamaño, por ejemplo. byte = 1 byte
` int = 4 bytes
`Object reference = 4 bytes (on a 32 bit system)
Entonces, si tiene 1 MB
memoria disponible en su máquina, puede asignar una matriz de byte[1024 * 1024]
o Object[256 * 1024]
.
Respuesta a su pregunta : puede asignar una matriz de tamaño (memoria máxima disponible / tamaño del elemento de matriz).
Resumen : teóricamente, el tamaño máximo de una matriz será Integer.MAX_VALUE
. Prácticamente depende de la cantidad de memoria que JVM
tenga y la cantidad que ya se haya asignado a otros objetos.
Traté de crear una matriz de bytes como esta
byte[] bytes = new byte[Integer.MAX_VALUE-x];
System.out.println(bytes.length);
Con esta configuración de ejecución:
-Xms4G -Xmx4G
Y la versión de Java:
Openjdk versión "1.8.0_141"
OpenJDK Runtime Environment (compilación 1.8.0_141-b16)
OpenJDK 64-Bit Server VM (compilación 25.141-b16, modo mixto)
Solo funciona para x> = 2, lo que significa que el tamaño máximo de una matriz es Integer.MAX_VALUE-2
Valores superiores que dan
Excepción en el subproceso "main" java.lang.OutOfMemoryError: el tamaño de la matriz solicitada excede el límite de VM en Main.main (Main.java:6)
Sí, hay límite en java array. Java utiliza un número entero como índice de la matriz y el almacenamiento máximo de números enteros por JVM es 2 ^ 32. para que pueda almacenar 2,147,483,647 elementos en la matriz.
En caso de que necesite más de la longitud máxima, puede usar dos matrices diferentes, pero el método recomendado es almacenar datos en un archivo. porque almacenar datos en el archivo no tiene límite. porque los archivos almacenados en sus controladores de almacenamiento pero matriz se almacenan en JVM. JVM proporciona espacio limitado para la ejecución del programa.
Número máximo de elementos de un array
es (2^31)−1
o2 147 483 647
Integer.MAX_VALUE - 1
, obtendrá "java.lang.OutOfMemoryError: el tamaño de la matriz solicitada excede el límite de VM". El número máximo de elementos en JDK 6 y superiores es Integer.MAX_VALUE - 2
= 2 147 483 645.
En realidad, es una limitación de Java que lo limita a 2 ^ 30-4 siendo 1073741820. No es 2 ^ 31-1. No sé por qué, pero lo probé manualmente en jdk. 2 ^ 30-3 todavía lanzando vm excepto
Editar: arreglado -1 a -4, marcado en Windows JVM