Citando Troubleshooting Guide for Java SE 6 with HotSpot VM
3.1.3 Particolare Messaggio: Requested array size exceeds VM limit
(linea in grassetto è mio):
Il dettaglio messaggio Requested array size exceeds VM limit
indica che l'applicazione (o le API utilizzato da tale applicazione) ha tentato di allocare una matrice che è più grande della dimensione dell'heap. Ad esempio, se un'applicazione tenta di allocare un array di 512 MB ma la dimensione massima dell'heap è 256 MB, verrà generato OutOfMemoryError
con il motivo Requested array size exceeds VM limit
. Nella maggior parte dei casi il problema è un problema di configurazione (dimensioni heap troppo piccole) o un errore che risulta in un'applicazione che tenta di creare un enorme array, ad esempio, quando il numero di elementi nell'array viene calcolato utilizzando un algoritmo che calcola una dimensione errata.
UPDATE: incoraggiati dalla @Pacerier ho fatto alcuni test rapido.Ho scritto un programma di esempio:
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);
}
}
}
ed eseguirlo con le seguenti opzioni JVM:
-Xms192m -Xmx192m -XX:NewRatio=2 -XX:SurvivorRatio=6 -XX:+PrintGCDetails
Questo è il loro significato:
- Il mucchio è 192 MiB (
-Xms192m -Xmx192m
)
- Lo spazio della giovane generazione (eden + survivor) è 64 MiB, la vecchia generazione è 128 MiB (
-XX:NewRatio=2
)
- Ogni spazio superstite (su due) è 8 MiB, quindi 48 MiB è lasciato per Eden (1: 6 rapporto,
-XX:SurvivorRatio=6
)
Durante il test ho scoperto quanto segue:
- Se il la matrice appena creata può essere inserita in eden (meno di 48 MiB), il programma funziona bene
- Sorprendentemente, quando la dimensione dell'array supera la dimensione di eden, ma può essere inserita in eden e nello spazio uno spazio (tra 48 e 56 MiB), JVM può allocare un singolo oggetto su eden e survivor (sovrapponendo tw o aree). Neat!
- Una volta che la dimensione dell'array supera l'eden + singolo sopravvissuto (oltre 56 MiB), l'oggetto appena creato viene posto direttamente nella vecchia generazione, scavalcando gli spazi eden e survivor. Questo significa anche che all'improvviso il GC completo viene eseguito sempre - molto male!
- mi può facilmente allocare 127 Mb di dati, ma cercando di destinare 129 MiB getterà
OutOfMemoryError: Java heap space
Questa è la linea di fondo - non è possibile creare un oggetto con dimensioni più grandi di vecchia generazione. Provare a farlo comporterà l'errore OutOfMemoryError: Java heap space
. Quindi, quando possiamo aspettarci un terribile Requested array size exceeds VM limit
?
Ho provato a eseguire lo stesso programma con oggetti molto più grandi. Colpendo il limite di lunghezza dell'array, sono passato a long[]
e potrei facilmente arrivare a 7 GiB. Con 128 MiB di heap massimo dichiarato JVM stava ancora lanciando OutOfMemoryError: Java heap space
(!) Sono riuscito ad attivare l'errore OutOfMemoryError: Requested array size exceeds VM limit
cercando di allocare 8 GiB in un singolo oggetto. Ho provato questo su un computer Linux a 32 bit con 3 GB di memoria fisica e 1 GB di swap.
Ciò detto, probabilmente non si dovrebbe mai dare questo errore. La documentazione sembra inaccurata/obsoleta, ma è vera in una conclusione: questo è probabilmente un bug dal momento che la creazione di tali enormi array è molto rara.
fonte
2012-01-29 12:38:28
See http://stackoverflow.com/questions/1880687/how-to-simulate-the-out-of-memory-requested-array-size-exceeds-vm-limit – skaffman