Java.lang.OutOfMemoryError: Java heap space

di il
6 risposte

Java.lang.OutOfMemoryError: Java heap space

Ciao a tutti!

Devo leggere da file e ordinare 20 milioni di interi in ordine crescente. In breve, quello che il mio programma fa è:

-Leggo gli interi sul file e li salvo all'interno di un ArrayList.
-Chiedo all'utente in che modo vuole ordinarli.
-Stampo a video i numeri ordinati.

Il mio programma funziona come dovrebbe se nel file metto solamente qualche numero di prova (tipo 20 numeri interi) ma nel momento in cui gli passo il file con 20 milioni di interi mi da errore:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOfRange(Unknown Source)
        at java.lang.String.<init>(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at usersimulation.UserSimulation.fileReader(UserSimulation.java:49)
        at usersimulation.UserSimulation.main(UserSimulation.java:77)
Per leggere i numeri contenuti in questo file ho dovuto dichiarare tutto come Long - altrimenti mi diceva che i numeri erano troppo grandi e non rientravano nel range degli int.

In realtà, io mi sto salvando questi 20 milioni di interi in un ArrayList solo per comodità. Se c'è un modo per leggerli e ordinarli direttamente all'interno del file che gli passo (senza modificarne il contenuto) e poi magari salvare quelli ordinati in un altro file nuovo mi va bene uguale!

Come posso risolvere?

6 Risposte

  • Re: Java.lang.OutOfMemoryError: Java heap space

    NoProg ha scritto:


    In realtà, io mi sto salvando questi 20 milioni di interi in un ArrayList solo per comodità. Se c'è un modo per leggerli e ordinarli direttamente all'interno del file che gli passo (senza modificarne il contenuto) e poi magari salvare quelli ordinati in un altro file nuovo mi va bene uguale!
    No, conviene avere tutto in memoria per un ordinamento.

    La soluzione più banale: aumentare il heap space, di quanto .... è da calcolare. Altra soluzione: usare una struttura dati più efficiente. Se usi un ArrayList, devi usare OGGETTI al suo interno (java.lang.Long) e questo porta via un bel po' di memoria con 20 milioni di valori.

    Alternativa: fai una prima scansione del file solo per contare il numero esatto di valori che hai. Poi sapendo la dimensione, istanzi un array (quindi NON ArrayList) long[] che è molto più "parco" come memoria rispetto ad usare oggetti in un ArrayList.
    Dato che un long occupa 8 byte, allora 8*20000000 = 160000000 bytes = ~160 Megabyte.

    Quindi diciamo per stare buoni che con un long[] di quella dimensione devi avere una JVM con almeno 200 MB di heap. Se invece vuoi continuare con un ArrayList<Long>, allora potresti considerare almeno 500 MB di heap.
  • Re: Java.lang.OutOfMemoryError: Java heap space

    andbin ha scritto:


    NoProg ha scritto:


    In realtà, io mi sto salvando questi 20 milioni di interi in un ArrayList solo per comodità. Se c'è un modo per leggerli e ordinarli direttamente all'interno del file che gli passo (senza modificarne il contenuto) e poi magari salvare quelli ordinati in un altro file nuovo mi va bene uguale!
    No, conviene avere tutto in memoria per un ordinamento.

    La soluzione più banale: aumentare il heap space, di quanto .... è da calcolare. Altra soluzione: usare una struttura dati più efficiente. Se usi un ArrayList, devi usare OGGETTI al suo interno (java.lang.Long) e questo porta via un bel po' di memoria con 20 milioni di valori.

    Alternativa: fai una prima scansione del file solo per contare il numero esatto di valori che hai. Poi sapendo la dimensione, istanzi un array (quindi NON ArrayList) long[] che è molto più "parco" come memoria rispetto ad usare oggetti in un ArrayList.
    Dato che un long occupa 8 byte, allora 8*20000000 = 160000000 bytes = ~160 Megabyte.

    Quindi diciamo per stare buoni che con un long[] di quella dimensione devi avere una JVM con almeno 200 MB di heap. Se invece vuoi continuare con un ArrayList<Long>, allora potresti considerare almeno 500 MB di heap.
    Ok grazie, mi sa che sono "costretto" ad usare comunque gli ArrayList perché il package che contiene gli algoritmi di ordinamento richiede degli ArrayList
  • Re: Java.lang.OutOfMemoryError: Java heap space

    NoProg ha scritto:


    Ok grazie, mi sa che sono "costretto" ad usare comunque gli ArrayList perché il package che contiene gli algoritmi di ordinamento richiede degli ArrayList
    Imposta il max heap a 700 MB, per iniziare a vedere se basta.

    (500 non mi pare bastino, ho fatto una prova veloce con un piccolo ciclo)
  • Re: Java.lang.OutOfMemoryError: Java heap space

    andbin ha scritto:


    NoProg ha scritto:


    Ok grazie, mi sa che sono "costretto" ad usare comunque gli ArrayList perché il package che contiene gli algoritmi di ordinamento richiede degli ArrayList
    Imposta il max heap a 700 MB, per iniziare a vedere se basta.

    (500 non mi pare bastino, ho fatto una prova veloce con un piccolo ciclo)
    Non riesco nemmeno a farlo partire col valore più alto che dovrebbe essere -Xms3072m se non erro
  • Re: Java.lang.OutOfMemoryError: Java heap space

    NoProg ha scritto:


    Non riesco nemmeno a farlo partire col valore più alto che dovrebbe essere -Xms3072m se non erro
    -Xms configura il valore "iniziale". Va impostato il valore massimo, -Xmx
  • Re: Java.lang.OutOfMemoryError: Java heap space

    andbin ha scritto:


    NoProg ha scritto:


    Non riesco nemmeno a farlo partire col valore più alto che dovrebbe essere -Xms3072m se non erro
    -Xms configura il valore "iniziale". Va impostato il valore massimo, -Xmx
    Si, scusa - errore di battitura!
Devi accedere o registrarti per scrivere nel forum
6 risposte