2011-11-30 18 views
75

Ho notato uno strano comportamento del mio compilatore di scala. Di tanto in tanto lancia un OutOfMemoryError durante la compilazione di una classe. Ecco il messaggio di errore:Come prevenire java.lang.OutOfMemoryError: PermGen space alla compilation Scala?

[info] Compiling 1 Scala source to /Users/gruetter/Workspaces/scala/helloscala/target/scala-2.9.0/test-classes... 
java.lang.OutOfMemoryError: PermGen space 
Error during sbt execution: java.lang.OutOfMemoryError: PermGen space 

Succede solo una volta ogni tanto e l'errore non è di solito gettato sulla successiva corsa di compilazione. Uso Scala 2.9.0 e compilo tramite SBT.

Qualcuno ha idea di quale potrebbe essere la causa di questo errore? Grazie in anticipo per i tuoi approfondimenti.

+0

Le risposte qui lavorare anche per 'java.lang.OutOfMemoryError: Metaspace' (il problema equivalente per Scala in esecuzione su Java 8) se si sostituisce 'MaxPermSize' con' MaxMetaspaceSize'. –

risposta

46

La causa di OutOfMemoryError: PermGen space è che non ha abbastanza permanent generation space :) Se si utilizza Oracle JVM, è necessario aggiungere il -XX:MaxPermSize=256M (o qualche altra quantità di spazio) argomento per lo script sbt. Per altre JVM, guarda la loro documentazione.

+1

Grazie Alexey. Ho già usato l'opzione -Xmx512M. Penso che dovrebbe avere lo stesso effetto, giusto? Ho comunque aggiunto il parametro -XX: MaxPermSize e vedo se l'errore persiste. – BumbleGee

+3

@BumbleGee No, la memoria aggiunta da '-Xmx' non può essere utilizzata per PermGen. –

+0

Grazie per aver chiarito questo, Alex. – BumbleGee

98

Uso HomeBrew per installare sbt su OS X. Supporta un argomento SBT_OPTS che può essere inserito nel file ~/.sbtconfig con export SBT_OPTS=-XX:MaxPermSize=256M.

+0

Grazie, ha funzionato per me! – Matthias

+1

Homebrew sembra essere una soluzione di pacchetto molto gestibile quando si sviluppa con SBT. :) – crockpotveggies

+0

lo script di installazione brew sbt imposta la memoria troppo piccola, eliminare il -Xmx512M nella parte java - cat 'which sbt' #!/Bin/sh test -f ~/.sbtconfig &&. ~/.sbtconfig exec java -Xmx512M $ {SBT_OPTS} -jar /usr/local/Cellar/sbt/0.13.1/libexec/sbt-launch.jar "$ @" –

3

Sembra una perdita di memoria in SBT per me come nel mio caso il programma viene compilato e viene eseguito correttamente per circa 3-5 volte prima di colpire l'eccezione che viene riparata dal riavvio SBT.

La soluzione più adeguata in effetti sembra essere il parametro -XX:MaxPermSize= JVM come suggerisce Alexey Romanov o riavviare periodicamente SBT se aiuta.

Ma c'è un altro modo interessante: provare a passare a Java 8. AFAIK non usa più PermGen ed è probabilmente immune a questa eccezione in questo modo.

Spero ancora che gli autori di SBT risolveranno questo problema nelle versioni future.

+0

Quindi Java 8 utilizza un sistema di memoria diverso? – Adrian

+0

Sì, per quanto ne so. https://www.google.com/search?q="java+8"+MaxPermSize – Ivan

+0

In J8 il perm gen viene appena inserito negli spazi dell'heap della memoria. – monkjack

4

Ho avuto questo problema, ho giocato con esso per 10 minuti guardando siti cercando di cambiare la dimensione della memoria.

Risulta ho risolto facendo,

user-profile$ sbt 

Poi,

sbt-project-name 0.1> clean 

Questo riesce per me.

1

Sto costruendo con il plugin sbt Jenkins e ho avuto gli stessi problemi. Sono stati risolti dopo aver copiato SBT_OPTS dal file sbt ai flag JVM di Jenkins Job Config.

35

Immagino che tu stia usando sbt 0.13.6 o superiore. Creare .sbtopts file nella root sbt del progetto con il seguente contenuto:

-J-Xmx4G 
-J-XX:MaxMetaspaceSize=1G 
-J-XX:MaxPermSize=1G 
-J-XX:+CMSClassUnloadingEnabled 

MaxMetaspaceSize è per Java 8, mentre MaxPermSize è per Java 7. Essi sono fondamentali per evitare errori di memoria legati sia per PermGen o metaspace esaurimento. Ovviamente, è consigliabile adattare i valori dei flag o aggiungere altri flag richiesti.

Maggiori dettagli e approcci alternativi possono essere trovati in questo blog post.

+0

Grande.Puoi anche inserire queste opzioni nel tuo file di configurazione globale; per me è '/ usr/local/etc/sbtopts' (per sbt installato con Homebrew su Mac). –

1

Originariamente usando un comando come:

java -jar /path/to/sbt-launch.jar test 

ho ottenuto prima OutOfMemoryError: spazio PermGen che ho risolto utilizzando -XX:MaxPermSize, e poi OutOfMemoryError: spazio heap Java, a cui -Xmx era il rimedio.

Quindi, nel mio caso, un comando come questo ha funzionato:

java -XX:MaxPermSize=256M -Xmx2048M -jar /path/to/sbt-launch.jar test 
0

cambio di blocco seguente codice nel file di sbt.sh e salvare la sua bella di lavoro.

get_mem_opts() { 
    local mem=${1:-1536} 
    local perm=$(($mem/4)) 
    (($perm > 256)) || perm=1024 //256 to 1024 
    (($perm < 1024)) || perm=2048 // 1024 to 2048 
    local codecache=$(($perm/2)) 

    echo "-Xms${mem}m -Xmx${mem}m -XX:MaxPermSize=${perm}m -XX:ReservedCodeCacheSize=${codecache}m" 
} 

o

utilizzando terminale per l'esportazione SBT config

export SBT_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=1024M -XX:MaxPermSize=2048M" 
Problemi correlati