【发布时间】:2014-06-04 21:20:15
【问题描述】:
我正在使用具有足够内存和 PermSize 的 sbt(请参阅下面的值),但我仍然不断收到内存错误。
[error] java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space
我的 sbt 脚本如下所示。
SBT_OPTS="-Xms1024M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=4028M" java $SBT_OPTS -jar `dirname $0`/sbt-launch.jar "$@"
我正在 IntelliJ 13 IDE 中进行更改,然后使用以下命令运行我的 Play 应用程序
$ ./sbt
[name-of-my-play-project] $ compile
[name-of-my-play-project] $ ~run
我也试过run 而不是~run。如果我使用 $./sbt 后跟 ~run 进行冷启动,我可以运行项目并访问页面。但是,经过一些代码更改后,Play 不再响应。
我尝试在另一台机器(也是 OS-X)上运行相同的项目,但我得到了类似的行为。我担心它不会一直发生,但经常发生以至于它让我没有效率,因为我必须重新启动 sbt 并从头开始玩,这完全违背了 Play2 框架的主要好处之一。
如果有人能帮助我从哪里开始寻找我的设置有什么问题,我将不胜感激。
我创建项目使用激活器,然后开始使用 sbt 为它。
更新 - YourKit 的屏幕截图(基于 @James 的建议)显示内存泄漏。
更新 2 YourKit 显示死锁(请参阅随附的屏幕截图)。我不确定这是否是问题的根本原因。我把它放在这里,以防有人可以提供更多关于正在发生的事情的见解。
更新 3 - 解决方案 经过超过 12 小时的不间断调试,我终于能够弄清楚了。这是一件非常简单的事情,我将在最后解释。由于我的代码中有很多 3rd 方库/插件(ReactiveMongo、Redis、...),我不确定其中是否有任何导致 OutOfMemory 错误。所以我只是删除了所有不需要的代码,直到我得到一个简单的控制器,其中一个方法只返回一个简单的“Hello world”。这个简单的程序我仍然遇到同样的错误。这意味着我的配置有问题。我尝试在我的project/build.properties 中将 sbt 版本更改为 0.13.5 (sbt.version=0.13.5),但仍然没有解决。我下载了新的 sbt-launch.jar (0.13.5),问题依然存在。同样,始终不变的一件事是错误从未改变。因此,由于某种原因,未设置 sbt 的标志。
我的 sbt bash 脚本看起来像(一行中的所有内容) -
SBT_OPTS="-Xms1024M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=4028M" java $SBT_OPTS -jar `dirname $0`/sbt-launch.jar "$@"
我改成
SBT_OPTS="-Xms1024M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=4028M"
java $SBT_OPTS -jar `dirname $0`/sbt-launch.jar "$@"
这解决了它。同样是类加载问题,但不是在我的代码中,而是在 sbt 的配置中。
【问题讨论】:
-
使用带有 G1 且不带 PermSize 的 java 8,或带有 G1 的 java 7。见Class Unloading in Java's G1 Garbage Collector (G1GC)
-
存在内存泄漏,使用不同的 JVM 或垃圾收集器不会修复内存泄漏,在 Java 8 中,这只是意味着它会占用系统内存,直到你用完所有内存系统崩溃。
标签: scala playframework-2.0 out-of-memory sbt permgen