¿Cómo evitar java.lang.OutOfMemoryError: espacio de PermGen en la compilación de Scala?


79

He notado un comportamiento extraño de mi compilador scala. Ocasionalmente arroja un OutOfMemoryError al compilar una clase. Aquí está el mensaje de error:

[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

Solo ocurre de vez en cuando y el error no suele aparecer en la siguiente ejecución de compilación. Uso Scala 2.9.0 y compilo a través de SBT.

¿Alguien tiene alguna idea de cuál podría ser la causa de este error? Gracias de antemano por sus ideas.


Las respuestas aquí también funcionan para java.lang.OutOfMemoryError: Metaspace(el problema equivalente para Scala que se ejecuta en Java 8) si reemplaza MaxPermSizecon MaxMetaspaceSize.
Brian McCutchon

Respuestas:


46

La causa OutOfMemoryError: PermGen spacees que no tiene suficiente espacio de generación permanente :) Si está utilizando Oracle JVM, debe agregar el -XX:MaxPermSize=256Margumento (o alguna otra cantidad de espacio) a su sbtscript. Para otras JVM, consulte su documentación.


1
Gracias Alexey. Ya utilicé la opción -Xmx512M. Creo que debería tener el mismo efecto, ¿verdad? No obstante, agregué el parámetro -XX: MaxPermSize y veo si el error persiste.
BumbleGee

3
@BumbleGee No, la memoria agregada por -Xmxno se puede usar para PermGen.
Alexey Romanov

Gracias por aclarar eso, Alex.
BumbleGee

6
Parece una pérdida de memoria en SBT ya que el programa se compila y se ejecuta con éxito unas 3-5 veces antes de lanzar la excepción que se corrige mediante el reinicio de SBT.
Ivan

4
Para la versión actual de sbtnecesitas en -J-XX:MaxPermSize=256Mlugar de -XX:MaxPermSize=256M. La respuesta de Tvaroh es más precisa y completa, además de que no se burla de la pregunta.
Daniel Darabos

99

Utilizo HomeBrew para instalar sbt en OS X. Es compatible con un SBT_OPTSargumento que se puede poner en un ~/.sbtconfigarchivo export SBT_OPTS=-XX:MaxPermSize=256M.


1
Homebrew parece ser una solución de paquete muy manejable cuando se desarrolla con SBT. :)
crockpotveggies

el script de instalación de sbt brew establece el máximo de memoria demasiado pequeño, elimine el -Xmx512M en la 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 "$ @"
ski_squaw

hay una buena configuración de SBT_OPTS
ski_squaw

funcionó para mí en Windows set SBT_OPTS = -XX: MaxPermSize = 512M
Alex Punnen

Use of ~/.sbtconfig is deprecated, please migrate global settings to /usr/local/etc/sbtopts, Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256M; support was removed in 8.0
Narfanator

36

Supuse que estás usando sbt 0.13.6 o superior. Cree un .sbtoptsarchivo en la raíz de su proyecto sbt con el siguiente contenido:

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

MaxMetaspaceSizees para Java 8 mientras que MaxPermSizees para Java 7. Son fundamentales para evitar errores de falta de memoria relacionados con el agotamiento de permgen o metaespacio . Por supuesto, considere la posibilidad de adaptar los valores de los indicadores o agregar cualquier otro indicador necesario.

Se pueden encontrar más detalles y enfoques alternativos en esta publicación de blog .


Excelente. También puede poner estas opciones en su archivo de configuración global; para mí es /usr/local/etc/sbtopts(para sbt instalado con Homebrew en Mac).
Brian McCutchon

5

Tuve este problema, jugué con él durante 10 minutos mirando sitios que intentaban cambiar el tamaño de la memoria.

Resulta que lo resolví por

user-profile$ sbt

Luego,

sbt-project-name 0.1> clean

Esto me lo aclaró.


4

Para mí, parece una pérdida de memoria en SBT, ya que en mi caso el programa se compila y se ejecuta correctamente durante unas 3-5 veces antes de hacer clic en la excepción que se soluciona mediante el reinicio de SBT.

De hecho, la solución más adecuada parece ser el -XX:MaxPermSize=parámetro JVM, como sugiere Alexey Romanov, o reiniciar SBT periódicamente si ayuda.

Pero hay otra forma interesante: intente cambiar a Java 8 . AFAIK, ya no usa PermGen y probablemente sea inmune a esta excepción de esta manera.

Todavía espero que los autores de SBT aborden este problema en versiones futuras.


Entonces, ¿Java 8 usa un sistema de memoria diferente?
Adrian

En J8, la generación de perm simplemente se coloca en los espacios de almacenamiento dinámico de la memoria.
sksamuel

Con Java 8 SBT no se compila, al menos en mi Mac. Tengo que cambiar a Java 7.
Siyuan Ren

Quizás estás haciendo algo mal, @CR Por lo que puedo recordar, lo probé con Java 8 en Linux en ese momento (cuando estaba en beta profunda) sin problemas visibles y lo estoy usando con Java 8 en Windows en este momento. ¿Quizás podría mostrarnos el mensaje de error del compilador que recibe?
Ivan

Gracias por la oferta de ayuda, pero decidí no volver a pasar por el complicado proceso. Me quedaré con Java 7 por el momento.
Siyuan Ren

2

Estoy construyendo con el complemento sbt de Jenkins y tuve los mismos problemas. Se resolvieron después de copiar SBT_OPTS del archivo sbt a los indicadores JVM de la configuración del trabajo de Jenkins.


2

Originalmente usando un comando como:

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

Primero obtuve OutOfMemoryError: espacio de PermGen que resolví usando -XX:MaxPermSize, y luego OutOfMemoryError: espacio de pila de Java , que -Xmxfue el remedio.

Entonces, en mi caso, un comando como este funcionó:

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

0

cambie el siguiente bloque de código en el archivo sbt.sh y guarde su funcionamiento bien.

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

usando la terminal para exportar la configuración de sbt

export SBT_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=1024M -XX:MaxPermSize=2048M"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.