Come affrontare "java.lang.OutOfMemoryError: Java heap space" errore (dimensione heap 64 MB)


Sto scrivendo un'applicazione Swing lato client (graphical font designer) su Java 5. Recentemente, sto riscontrando un errore java.lang.OutOfMemoryError: Java heap space perché non sono conservativo sull'utilizzo della memoria. L'utente può aprire un numero illimitato di file e il programma mantiene gli oggetti aperti nella memoria. Dopo una rapida ricerca ho trovato Ergonomia nella macchina virtuale Java 5.0 e altri che dicono sulla macchina Windows che la JVM ha la dimensione massima dell'heap come 64MB.

Dato questo situazione, come dovrei affrontare questo vincolo?

Potrei aumentare la dimensione massima dell'heap usando l'opzione della riga di comando su java, ma ciò richiederebbe di capire la RAM disponibile e scrivere un programma o uno script di avvio. Inoltre, l'aumento a un massimo finito non elimina in ultima analisi il problema.

Potrei riscrivere parte del mio codice per mantenere gli oggetti nel file system frequentemente (usare il database è la stessa cosa) per liberare la memoria. Potrebbe funzionare, ma è probabilmente anche molto lavoro.

Se potessi indicarmi i dettagli delle idee di cui sopra o alcune alternative come memoria virtuale automatica, estendendo dinamicamente la dimensione dell'heap , sarebbe fantastico.

Author: Bhaskara Arani, 2008-09-01

18 answers

In definitiva hai sempre un massimo finito di heap da usare indipendentemente dalla piattaforma su cui stai eseguendo. In Windows 32 bit questo è di circa 2 GB (non specificamente heap ma quantità totale di memoria per processo). Succede solo che Java scelga di rendere il default più piccolo (presumibilmente in modo che il programmatore non possa creare programmi con allocazione di memoria in fuga senza incorrere in questo problema e dover esaminare esattamente cosa stanno facendo).

Quindi questo dato ci sono diversi approcci che potresti adottare per determinare la quantità di memoria di cui hai bisogno o per ridurre la quantità di memoria che stai utilizzando. Un errore comune con i linguaggi garbage collected come Java o C# è quello di mantenere i riferimenti agli oggetti che non si utilizzano più o allocare molti oggetti quando è possibile riutilizzarli. Finché gli oggetti hanno un riferimento a loro, continueranno a utilizzare lo spazio heap poiché il garbage collector non li eliminerà.

In questo caso è possibile utilizzare un Java memory profiler per determinare quali metodi nel programma stanno allocando un numero elevato di oggetti e quindi determinare se esiste un modo per assicurarsi che non siano più referenziati o per non allocarli in primo luogo. Un'opzione che ho usato in passato è " JMP " http://www.khelekore.org/jmp/.

Se si determina che si stanno allocando questi oggetti per un motivo e si deve mantenere i riferimenti (a seconda di cosa si sta facendo, potrebbe essere il caso), si sarà solo necessario aumentare la dimensione massima dell'heap quando si avvia il programma. Tuttavia, una volta eseguita la profilazione della memoria e compreso come vengono assegnati i tuoi oggetti, dovresti avere un'idea migliore di quanta memoria hai bisogno.

In generale, se non è possibile garantire che il programma venga eseguito in una quantità limitata di memoria (forse a seconda della dimensione dell'input), si verificherà sempre questo problema. Solo dopo aver esaurito tutto questo sarà necessario esaminare gli oggetti di memorizzazione nella cache su disco ecc. A questo punto dovresti avere una buona ragione per dire "Ho bisogno di Xgb di memoria" per qualcosa e non puoi aggirarlo migliorando i tuoi algoritmi o i modelli di allocazione della memoria. Generalmente questo sarà solo il caso di algoritmi che operano su set di dati di grandi dimensioni (come un database o un programma di analisi scientifica) e quindi tecniche come il caching e l'IO mappato in memoria diventano utili.

 196
Author: Ben Childs, 2017-06-02 21:52:52

Eseguire Java con l'opzione della riga di comando -Xmx, che imposta la dimensione massima dell'heap.

Vedi qui per i dettagli..

 101
Author: Dave Webb, 2013-07-11 08:42:08

È possibile specificare per progetto la quantità di spazio heap desiderata dal progetto

Di seguito è riportato per Eclipse Helios / Juno / Kepler :

Fare clic con il tasto destro del mouse su

 Run As - Run Configuration - Arguments - Vm Arguments, 

Quindi aggiungi questo

-Xmx2048m
 77
Author: allenhwkim, 2016-03-08 08:02:54

Aumentare la dimensione dell'heap non è una "correzione", è un "gesso", temporaneo al 100%. Andrà in crash di nuovo in qualche altra parte. Per evitare questi problemi, scrivere codice ad alte prestazioni.

  1. Usa le variabili locali laddove possibile.
  2. Assicurarsi di selezionare l'oggetto corretto (ES: Selezione tra String, StringBuffer e StringBuilder)
  3. Usa un buon sistema di codice per il tuo programma (ES: Usando variabili statiche VS variabili non statiche)
  4. Altre cose che potrebbero funzionare sul tuo codice.
  5. Prova a muoverti con il multy THREADING
 30
Author: Yohan Weerasinghe, 2017-06-02 21:58:26

Grande avvertimento - - - - nel mio ufficio, stavamo scoprendo che (su alcune macchine Windows) non potevamo allocare più di 512m per Java heap. Ciò si è rivelato essere dovuto al prodotto Kaspersky anti-virus installato su alcune di queste macchine. Dopo aver disinstallato quel prodotto AV, abbiamo scoperto che potevamo allocare almeno 1.6 gb, cioè-Xmx1600m (m è obbligatorio in altro modo porterà ad un altro errore "Troppo piccolo heap iniziale") funziona.

Non ho idea se ciò accada con altri prodotti AV ma presumibilmente questo accade perché il programma AV sta riservando un piccolo blocco di memoria in ogni spazio di indirizzi, impedendo così una singola allocazione veramente grande.

 28
Author: David, 2017-07-06 13:35:43

L'argomento VM ha funzionato per me in eclipse. Se si utilizza eclipse versione 3.4, effettuare le seguenti operazioni

Vai a Run --> Run Configurations --> quindi seleziona il progetto in maven build - > quindi seleziona la scheda "JRE" - > quindi inserisci -Xmx1024m.

In alternativa puoi fare Run --> Run Configurations --> select the "JRE" tab --> quindi inserire - Xmx1024m

Questo dovrebbe aumentare l'heap di memoria per tutte le build/progetti. La dimensione della memoria di cui sopra è 1 GB. È possibile ottimizzare il modo desiderato.

 18
Author: loveall, 2015-01-12 14:50:54

Sì, con-Xmx è possibile configurare più memoria per la JVM. Per essere sicuri di non perdere o sprecare memoria. Prendi un dump heap e usa l'analizzatore di memoria Eclipse per analizzare il consumo di memoria.

 15
Author: kohlerm, 2008-10-09 08:22:25

Vorrei aggiungere raccomandazioni da oracle risoluzione dei problemi articolo

Eccezione nel thread nome_filo: java.lang.OutOfMemoryError: spazio heap Java

Il messaggio di dettaglio Java heap space indica che l'oggetto non può essere allocato nell'heap Java. Questo errore non implica necessariamente una perdita di memoria

Possibili cause:

  1. Semplice problema di configurazione, in cui la dimensione heap specificata è insufficiente per l'applicazione.

  2. L'applicazione contiene involontariamente riferimenti agli oggetti e ciò impedisce che gli oggetti vengano raccolti.

  3. Uso eccessivo di finalizzatori.

Un'altra potenziale fonte di questo errore si presenta con applicazioni che fanno un uso eccessivo di finalizzatori. Se una classe ha un metodo finalize, gli oggetti di quel tipo non hanno il loro spazio recuperato in garbage tempo di raccolta

Dopo garbage collection, gli oggetti vengono messi in coda per finalizzazione, che avviene in un secondo momento. i finalizzatori vengono eseguiti da un thread demone che serve la coda di finalizzazione. Se il thread finalizzatore non riesce a tenere il passo con la coda di finalizzazione, l'heap Java potrebbe riempirsi e questo tipo di eccezione OutOfMemoryError verrà generata.

Uno scenario che può causare questa situazione è quando un l'applicazione crea thread ad alta priorità che causano l'aumento della coda di finalizzazione a una velocità superiore alla velocità con cui il thread di finalizzatore sta eseguendo la manutenzione della coda.

 8
Author: Ravindra babu, 2017-06-29 15:35:27

Seguire i passaggi seguenti:

  1. Apri catalina.sh da tomcat / bin.

  2. Chnage JAVA_OPTA a

    JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m 
    -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m 
    -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
    
  3. Riavvia il tuo tomcat

 7
Author: Pradip Bhatt, 2017-07-03 17:59:03

Ho letto da qualche altra parte che puoi provare - catch java.lang.OutOfMemoryError e sul blocco catch, è possibile liberare tutte le risorse che si sa potrebbero utilizzare un sacco di memoria, chiudere le connessioni e così via, quindi fare un sistema.gc() quindi riprova tutto ciò che stavi per fare.

Un altro modo è questo anche se, non so se funzionerebbe, ma attualmente sto testando se funzionerà sulla mia applicazione.

L'idea è di fare Garbage collection chiamando System.gc () che è noto per aumentare la memoria libera. Puoi continuare a controllarlo dopo che viene eseguito un codice di memoria.

//Mimimum acceptable free memory you think your app needs
long minRunningMemory = (1024*1024);

Runtime runtime = Runtime.getRuntime();

if(runtime.freeMemory()<minRunningMemory)
 System.gc();
 6
Author: mwangi, 2010-08-17 08:19:44

Ho affrontato lo stesso problema della dimensione dell'heap java. Ho due soluzioni se stai usando java 5(1.5).

1st:-basta installare jdk1.6 e andare alle preferenze di eclipse e impostare il percorso jre di jav1 1.6 come è stato installato.

2nd:-Controlla il tuo argomento VM e lascia che sia qualunque cosa sia. basta aggiungere una riga sotto di tutti gli argomenti presenti negli argomenti VM come -Xms512m-Xmx512m-XX:MaxPermSize=...m (192m).

Penso che funzionerà...

 6
Author: Soumya Sandeep Mohanty, 2011-05-10 18:48:49

Un modo semplice per risolvere OutOfMemoryError in java è aumentare la dimensione massima dell'heap usando le opzioni JVM -Xmx512M, questo risolverà immediatamente il tuo OutOfMemoryError. Questa è la mia soluzione preferita quando esco da Memoryerror in Eclipse, Maven o ANT durante la costruzione del progetto perché in base alle dimensioni del progetto si può facilmente esaurire la memoria.

Ecco un esempio di aumento della dimensione massima dell'heap di JVM, inoltre è meglio mantenere la razione-Xmx a-Xms 1: 1 o 1: 1.5 se si imposta la dimensione dell'heap in la tua applicazione java.

export JVM_ARGS="-Xms1024m -Xmx1024m"

Collegamento di riferimento

 6
Author: chaukssey, 2012-06-20 10:34:39

Se è necessario monitorare l'utilizzo della memoria in fase di runtime, il java.lang.il pacchetto di gestione offre MBEAN che possono essere utilizzati per monitorare i pool di memoria nella VM (ad esempio, eden space, tenured generation ecc.)

Lo spazio heap libero riportato da questi MBEAN varierà notevolmente a seconda del comportamento GC, in particolare se l'applicazione genera molti oggetti che sono successivamente GC-ed. Un possibile approccio è quello di monitorare lo spazio heap libero dopo ogni full-GC, che potresti essere in grado di utilizzare per prendere una decisione sulla liberazione della memoria persistendo gli oggetti.

In definitiva, la soluzione migliore è limitare il più possibile la conservazione della memoria mentre le prestazioni rimangono accettabili. Come notato in un commento precedente, la memoria è sempre limitata, ma la tua app dovrebbe avere una strategia per affrontare l'esaurimento della memoria.

 5
Author: Leigh, 2008-10-09 12:04:30

Si noti che se è necessario in una situazione di distribuzione, considerare l'utilizzo di Java WebStart (con una versione "ondisk", non quella di rete - possibile in Java 6u10 e versioni successive) in quanto consente di specificare i vari argomenti alla JVM in modo multipiattaforma.

Altrimenti avrai bisogno di un launcher specifico del sistema operativo che imposta gli argomenti di cui hai bisogno.

 3
Author: Thorbjørn Ravn Andersen, 2009-05-19 04:45:22

Per impostazione predefinita per lo sviluppo JVM utilizza dimensioni ridotte e configurazione ridotta per altre funzionalità correlate alle prestazioni. Ma per la produzione è possibile sintonizzare ad esempio (Inoltre può esistere una configurazione specifica del server delle applicazioni) - > (Se non c'è ancora abbastanza memoria per soddisfare la richiesta e l'heap ha già raggiunto la dimensione massima, si verificherà un OutOfMemoryError)

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size

-XX:ParallelGCThreads=8
-XX:+CMSClassUnloadingEnabled
-XX:InitiatingHeapOccupancyPercent=70
-XX:+UnlockDiagnosticVMOptions
-XX:+UseConcMarkSweepGC
-Xms512m
-Xmx8192m
-XX:MaxPermSize=256m (in java 8 optional)

Ad esempio: Su piattaforma linux per la modalità di produzione impostazioni preferibili.

Dopo aver scaricato e configurato server in questo modo http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7 /

1.crea setenv.sh file nella cartella / opt / tomcat / bin /

   touch /opt/tomcat/bin/setenv.sh

2.Apri e scrivi questo parametro per impostare la modalità preferibile.

nano  /opt/tomcat/bin/setenv.sh 

export CATALINA_OPTS="$CATALINA_OPTS -XX:ParallelGCThreads=8"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+CMSClassUnloadingEnabled"
export CATALINA_OPTS="$CATALINA_OPTS -XX:InitiatingHeapOccupancyPercent=70"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UnlockDiagnosticVMOptions"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseConcMarkSweepGC"
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=256M"

3.service tomcat restart

Si noti che la JVM utilizza più memoria del solo heap. Biru I metodi Java, gli stack di thread e gli handle nativi sono allocati in memoria separato dall'heap, così come JVM interno strutture dati.

 3
Author: Musa, 2018-03-03 12:32:02

Se continui ad allocare e mantenere i riferimenti all'oggetto, riempirai qualsiasi quantità di memoria che hai.

Un'opzione è quella di chiudere e aprire un file trasparente quando cambiano scheda (si mantiene solo un puntatore al file e quando l'utente cambia scheda, si chiudono e si puliscono tutti gli oggetti... renderà il cambio di file più lento... ma...), e forse mantenere solo 3 o 4 file in memoria.

Un'altra cosa che dovresti fare è, quando l'utente apre un file, caricarlo e intercettare qualsiasi OutOfMemoryError, quindi (poiché non è possibile aprire il file) chiudi quel file, pulisci i suoi oggetti e avvisa l'utente che dovrebbe chiudere i file inutilizzati.

La tua idea di estendere dinamicamente la memoria virtuale non risolve il problema, poiché la macchina è limitata alle risorse, quindi dovresti fare attenzione e gestire i problemi di memoria (o almeno, fai attenzione con loro).

Un paio di suggerimenti che ho visto con perdite di memoria è:

> > Tieni presente che se metti qualcosa in una raccolta e poi dimenticalo, hai ancora un forte riferimento ad esso, quindi annulla la raccolta, puliscila o fai qualcosa con essa... in caso contrario, troverete una perdita di memoria difficile da trovare.

Maybe> Forse, usando raccolte con riferimenti deboli (weakhashmap...) può aiutare con problemi di memoria, ma tu devi fare attenzione, perché potresti scoprire che l'oggetto che cerchi è stato raccolto.

> > Un'altra idea che ho trovato è sviluppare una collezione persistente che memorizzati su oggetti di database meno utilizzati e caricati in modo trasparente. Questo sarebbe probabilmente l'approccio migliore...

 0
Author: SoulWanderer, 2010-09-29 07:47:13

Per quanto riguarda netbeans, è possibile impostare la dimensione massima dell'heap per risolvere il problema. In primo luogo, vai su 'Esegui', quindi- > 'Imposta configurazione del progetto'- > 'Personalizza' - > 'esegui' della finestra visualizzata - > 'Opzione VM' - > compila '- Xms2048m-Xmx2048m'.

 0
Author: Xiaogang, 2017-06-12 22:56:06

Se questo problema si verifica in Wildfly 8 e JDK1.8,è necessario specificare le impostazioni MaxMetaSpace anziché le impostazioni PermGen.

Ad esempio abbiamo bisogno di aggiungere sotto la configurazione in setenv.sh file di wildfly. JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"

Per ulteriori informazioni, si prega di controllare Wildfly Heap Problema

 0
Author: satish, 2017-08-28 05:10:30