2011-11-30 106 views
75

我注意到了我的scala编译器的一个奇怪的行为。编译类时偶尔会引发OutOfMemoryError。这里的错误消息:如何防止java.lang.OutOfMemoryError:Scala编译时的PermGen空间?

[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 

它只是在一段时间发生的一次错误通常不扔在后续编译运行。我使用Scala 2.9.0并通过SBT编译。

没有任何人有一个线索,以什么可能是这个错误的原因是什么?提前感谢您的见解。

+0

的答案也是'java.lang.OutOfMemoryError工作:Metaspace'(针对Java运行斯卡拉等效问题8)如果你用'MaxMetaspaceSize'替换'MaxPermSize'。 –

回答

46

OutOfMemoryError: PermGen space的原因是,它没有足够的permanent generation space :)如果你使用的是Oracle JVM,您需要将-XX:MaxPermSize=256M(或空间的一些其他金额)参数添加到您的sbt脚本。对于其他JVM,请看他们的文档。

+1

谢谢阿列克谢。我已经使用了-Xmx512M选项。我认为这应该有同样的效果,对吧?我已经添加了-XX:MaxPermSize参数,看看错误是否仍然存在。 – BumbleGee

+3

@BumbleGee不,由'-Xmx'添加的内存不能用于PermGen。 –

+0

谢谢你澄清,亚历克斯。 – BumbleGee

98

我使用HomeBrew在OS X上安装sbt。它支持SBT_OPTS参数,该参数可以放在~/.sbtconfig文件中,其中export SBT_OPTS=-XX:MaxPermSize=256M

+0

谢谢,这对我有用! – Matthias

+1

使用SBT开发Homebrew似乎是一个非常易于管理的软件包解决方案。 :) – crockpotveggies

+0

sbt brew安装脚本设置内存最大值太小,摆脱java部分中的-Xmx512M -cat'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

它看起来像在SBT内存泄漏对我来说在我的案件的程序编译和运行成功约3-5次打击是由SBT重启固定异常之前。

最合适的解决方案确实似乎是-XX:MaxPermSize= JVM参数作为阿列克谢·罗曼诺夫建议或者定期重新启动SBT是否有帮助。

但还有另一种有趣的方法:尝试切换到Java 8。 AFAIK它不再使用PermGen,并且可能免于这种异常。

我仍然希望SBT的作者将在未来的版本中解决这个问题。

+0

因此,Java 8使用不同的内存系统? – Adrian

+0

是的,据我所知。 https://www.google.com/search?q="java+8"+MaxPermSize – Ivan

+0

在J8中,perm gen只是卷入内存堆空间。 – monkjack

4

我有这个问题,发挥它周围10分钟看试图改变内存大小网站。

事实证明,我的解决它,

user-profile$ sbt 

然后,

sbt-project-name 0.1> clean 

这清除它适合我。

1

我正在建造Jenkins sbt插件并且有同样的问题。将SBT_OPTS从sbt文件复制到Jenkins作业配置的JVM标志后,它们得到解决。

35

我假设你正在使用SBT 0.13.6或更高。创建.sbtopts文件在您SBT项目的根具有以下内容:

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

MaxMetaspaceSize是Java 8,而MaxPermSize是Java 7。他们是至关重要的,以防止出现相关的内存不足的错误要么的PermGen元空间疲惫。当然,考虑调整标志值或添加所需的其他标志。

更多细节和替代方法可以在这blog post找到。

+0

太好了。您也可以将这些选项放入您的全局配置文件中;对我来说,它是'/ usr/local/etc/sbtopts'(用于在Mac上安装Homebrew的sbt)。 –

1

最初使用如下命令:

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

我得到了第一的OutOfMemoryError:PermGen的空间我使用-XX:MaxPermSize解决,然后OutOfMemoryError异常:Java堆空间,到-Xmx是补救。

所以在我的情况下,这样的命令工作:

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

变化下面的代码块sbt.sh文件并保存其工作的罚款。

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" 
} 

使用终端SBT配置这里出口

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