Citando Mensaje Troubleshooting Guide for Java SE 6 with HotSpot VM
3.1.3 detalle: Requested array size exceeds VM limit
(en línea en negrita es mía):
El detalle mensaje Requested array size exceeds VM limit
indica que la aplicación (o API utilizado por que la aplicación) intentado asigna una matriz que es más grande que el tamaño del montón. Por ejemplo, si una aplicación intenta asignar una matriz de 512 MB pero el tamaño de almacenamiento dinámico máximo es de 256 MB, se generará OutOfMemoryError
con el motivo Requested array size exceeds VM limit
. En la mayoría de los casos, el problema es configuración problema (tamaño de pila demasiado pequeño) o un error que da como resultado una aplicación que intenta crear un gran conjunto, por ejemplo, cuando se calcula el número de elementos en el conjunto un algoritmo que calcula un tamaño incorrecto.
ACTUALIZACIÓN: animado por el @Pacerier lo hice alguna prueba rápida.Escribí un programa de ejemplo:
public class VmLimitTest {
public static final int SIZE = 2;
public static void main(String[] args) throws InterruptedException {
while(true) {
byte[] a = new byte[SIZE * 1024 * 1024];
TimeUnit.MILLISECONDS.sleep(10);
}
}
}
y ejecutarlo con las siguientes opciones de JVM:
-Xms192m -Xmx192m -XX:NewRatio=2 -XX:SurvivorRatio=6 -XX:+PrintGCDetails
Esto es lo que significan:
- Todo el montón es 192 MiB (
-Xms192m -Xmx192m
)
- El espacio de la generación joven (eden + survivor) es de 64 MiB, la generación anterior es de 128 MiB (
-XX:NewRatio=2
)
- Cada espacio superviviente (de dos) es 8 MiB, por lo 48 MiB se deja para eden (relación 1: 6,
-XX:SurvivorRatio=6
)
Mientras que la prueba descubrí la siguiente:
- Si el matriz recién creada puede caber en eden (menos de 48 MiB), el programa funciona bien
- Sorprendentemente, cuando el tamaño de la matriz excede el tamaño eden, pero puede caber en eden y un espacio superviviente (entre 48 y 56 MiB), JVM puede asignar un único objeto en eden y survivor (superposición de tw o áreas). ¡Ordenado!
- Una vez que el tamaño de la matriz excede eden + superviviente individual (por encima de 56 MiB) el objeto recién creado se coloca directamente en la generación anterior, evitando los espacios de eden y survivor. Esto también significa que de repente se realiza un GC completo todo el tiempo, ¡muy mal!
- que se puede asignar fácilmente 127 MiB de datos, sino intentar asignar 129 MiB tirará
OutOfMemoryError: Java heap space
Ésta es la línea de fondo - no se puede crear un objeto con tamaño mayor de antigua generación. Si intenta hacerlo, se producirá el error OutOfMemoryError: Java heap space
. Entonces, ¿cuándo podemos esperar Requested array size exceeds VM limit
terrible?
Intenté ejecutar el mismo programa con objetos mucho más grandes. Al tocar el límite de longitud de la matriz, cambié a long[]
y podría llegar fácilmente a 7 GiB. Con 128 MiB de max heap declarada, la JVM todavía estaba lanzando OutOfMemoryError: Java heap space
(!) Logré desencadenar el error OutOfMemoryError: Requested array size exceeds VM limit
tratando de asignar 8 GiB en un solo objeto. Probé esto en una computadora Linux de 32 bits con 3 GiB de memoria física y 1 GiB de intercambio.
Dicho esto, probablemente nunca deberías encontrar este error. La documentación parece inexacta/obsoleta, pero es cierta en una conclusión: esto es probablemente un error ya que la creación de matrices de este tipo es muy poco común.
Ver http://stackoverflow.com/questions/1880687/how-to-simulate-the-out-of-memory-required-array-size-exceeds-vm-limit – skaffman