Domanda

Ricevo il seguente errore durante l'esecuzione di un programma multi-threading

java.lang.OutOfMemoryError: Java heap space

L'errore precedente si è verificato in uno dei thread.

  1. Per quanto ne so, lo spazio heap è occupato solo da variabili di istanza.Se questo è corretto, allora perché questo errore si è verificato dopo aver funzionato correttamente per qualche tempo poiché lo spazio per le variabili di istanza viene assegnato al momento della creazione dell'oggetto.

  2. C'è un modo per aumentare lo spazio heap?

  3. Quali modifiche dovrei apportare al mio programma in modo che occupi meno spazio nell'heap?

È stato utile?

Soluzione

Se vuoi aumentare lo spazio heap, puoi usare java -Xms<initial heap size> -Xmx<maximum heap size> sulla riga di comando.Per impostazione predefinita, i valori si basano sulla versione JRE e sulla configurazione del sistema.Puoi scoprirlo ulteriori informazioni sulle opzioni VM sul sito Web Java.

Tuttavia, consiglierei di profilare la tua applicazione per scoprire perché viene consumata la dimensione dell'heap.NetBeans ha un ottimo profiler incluso con esso.Credo che usi il jvisualvm sotto il cappuccio.Con un profiler, puoi provare a scoprire dove vengono creati molti oggetti, quando gli oggetti vengono sottoposti a garbage collection e altro ancora.

Altri suggerimenti

1.- Sì, ma si riferisce più o meno all'intera memoria utilizzata dal tuo programma.

2.- Sì, vedere le opzioni Java VM

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size

Cioè

java -Xmx2g assegna 2 gigabyte di ram al massimo alla tua app

Ma dovresti prima vedere se non hai una perdita di memoria.

3.- Dipende dal programma.Prova a individuare le perdite di memoria.Sarebbe troppo difficile rispondere a questa domanda.Ultimamente puoi creare un profilo utilizzando JConsole per cercare di scoprire dove andrà a finire la tua memoria

Potresti voler visitare questo sito per saperne di più sulla memoria nella JVM:http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage

L'ho trovato utile da usare visualgc per osservare come si riempiono le diverse parti del modello di memoria, per determinare cosa cambiare.

È difficile determinare quale parte della memoria è stata riempita, quindi visualgc, poiché potresti voler semplicemente cambiare la parte che presenta un problema, piuttosto che semplicemente dire,

Bene!Darò 1G di RAM alla JVM.

Cerca di essere più preciso su quello che stai facendo, alla lunga probabilmente troverai il programma migliore per questo.

Per determinare dove potrebbe essere la perdita di memoria è possibile utilizzare i test unitari, testando qual era la memoria prima del test e dopo, e se c'è un cambiamento troppo grande allora potresti voler esaminarlo, ma devi farlo esegui il controllo mentre il test è ancora in corso.

Per aumentare la dimensione dell'heap è possibile utilizzare l'argomento -Xmx all'avvio di Java;per esempio.

-Xmx256M

Puoi ottenere la dimensione della memoria heap tramite il programma seguente.

public class GetHeapSize {
    public static void main(String[] args) {
        long heapsize = Runtime.getRuntime().totalMemory();
        System.out.println("heapsize is :: " + heapsize);
    }
} 

quindi di conseguenza puoi aumentare la dimensione dell'heap anche usando:java-Xmx2ghttp://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

  1. Per quanto ne so, lo spazio heap è occupato solo da variabili di istanza.Se questo è corretto, allora perché questo errore si è verificato dopo aver funzionato correttamente per qualche tempo poiché lo spazio per le variabili di istanza viene assegnato al momento della creazione dell'oggetto.

Ciò significa che stai creando più oggetti nella tua applicazione in un periodo di tempo continuo.I nuovi oggetti verranno archiviati nella memoria heap e questo è il motivo della crescita della memoria heap.

L'heap non contiene solo variabili di istanza.Memorizzerà tutti i tipi di dati non primitivi (Oggetti).La durata di vita di questi oggetti può essere breve (blocco del metodo) o lunga (finché non viene fatto riferimento all'oggetto nell'applicazione)

  1. C'è un modo per aumentare lo spazio heap?

SÌ.Dai un'occhiata a questo oracolo articolo per ulteriori dettagli.

Esistono due parametri per impostare la dimensione dell'heap:

-Xms:, che imposta la dimensione heap iniziale e minima

-Xmx:, che imposta la dimensione massima dell'heap

  1. Quali modifiche dovrei apportare al mio programma in modo che occupi meno spazio nell'heap?

Dipende dalla tua applicazione.

  1. Imposta la memoria heap massima in base ai requisiti dell'applicazione

  2. Non causare perdite di memoria nella tua applicazione

  3. Se trovi perdite di memoria nella tua applicazione, trova la causa principale con l'aiuto di strumenti di profilazione come STUOIA, Macchina virtuale visiva , jconsole eccetera.Una volta trovata la causa principale, correggere le perdite.

Note importanti da Oracle articolo

Causa:Il messaggio dettagliato Spazio heap Java indica che non è stato possibile allocare l'oggetto nell'heap Java.Questo errore non implica necessariamente una perdita di memoria.

Possibili ragioni:

  1. Configurazione errata (non allocare memoria sufficiente)
  2. L'applicazione conserva involontariamente riferimenti a oggetti e ciò impedisce la raccolta dei rifiuti degli oggetti
  3. Applicazioni che fanno un uso eccessivo di finalizzatori.Se una classe ha un metodo finalize, gli oggetti di quel tipo non avranno il loro spazio recuperato al momento della raccolta dei rifiuti. Se il thread del finalizzatore non riesce a tenere il passo con la coda di finalizzazione, l'heap Java potrebbe riempirsi e verrebbe generato questo tipo di eccezione OutOfMemoryError.

In una nota diversa, utilizzare migliori algoritmi di Garbage Collection ( CMS O G1GC)

dai un'occhiata a questo domanda per comprendere G1GC

  1. Nella maggior parte dei casi, il codice non è ottimizzato.Rilascia quegli oggetti che ritieni non saranno più necessari.Evita ogni volta la creazione di oggetti nel tuo loop.Prova a utilizzare le cache.Non so come sta andando la tua richiesta.Ma nella programmazione vale anche una regola di vita normale

    Prevenire è meglio che curare."Non creare oggetti inutili"

  1. Le variabili locali si trovano nello stack.Lo spazio heap è occupato da oggetti.

  2. Puoi usare il -Xmx opzione.

  3. Fondamentalmente lo spazio heap viene utilizzato ogni volta che assegni un nuovo oggetto con new e liberato qualche tempo dopo che non si fa più riferimento all'oggetto.Quindi assicurati di non conservare riferimenti ad oggetti che non ti servono più.

No, penso che tu stia pensando allo spazio dello stack.Lo spazio heap è occupato da oggetti.Il modo per aumentarlo è -Xmx256m, sostituendo 256 con l'importo necessario sulla riga di comando.

In netbeans, vai alla barra degli strumenti 'Esegui', --> 'Imposta configurazione progetto' --> 'Personalizza' --> 'esegui' della finestra visualizzata --> 'Opzione VM' --> compila '-Xms2048m -Xmx2048m'.Potrebbe risolvere il problema della dimensione dell'heap.

Per evitare questa eccezione, se stai usando JUnit e Spring prova ad aggiungere questo in ogni classe di test:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top