play framework 中的 java.lang.OutOfMemoryError: PermGen space

8

编辑:- 在运行我的项目时输入 play ~run

如何解决这个问题, 我的项目处于测试阶段。每天5-6个小时后它突然停止并给出以下错误。 该怎么做才能解决这个错误?
我正在使用scala 2.1和playframework 2.2开发这个项目。

    java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:188)
Caused by: java.lang.OutOfMemoryError: PermGen space
    at sun.misc.Unsafe.defineClass(Native Method)
    at sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:63)
    at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:399)
    at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:396)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:395)
    at sun.reflect.MethodAccessorGenerator.generateSerializationConstructor(MethodAccessorGenerator.java:113)
    at sun.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:331)
    at java.io.ObjectStreamClass.getSerializableConstructor(ObjectStreamClass.java:1376)
    at java.io.ObjectStreamClass.access$1500(ObjectStreamClass.java:72)
    at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:493)
    at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:468)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:468)
    at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:365)
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:602)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1706)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1344)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space
[error] Total time: 11065 s, completed 8 Feb, 2014 6:12:52 PM
1. Waiting for source changes... (press enter to interrupt)

java.lang.OutOfMemoryError: PermGen space
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) java.lang.reflect.InvocationTargetException
[error] Total time: 4 s, completed 8 Feb, 2014 6:12:57 PM
2. Waiting for source changes... (press enter to interrupt)

java.lang.OutOfMemoryError: PermGen space
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) java.lang.reflect.InvocationTargetException
[error] Total time: 4 s, completed 8 Feb, 2014 6:13:08 PM
3. Waiting for source changes... (press enter to interrupt)

java.lang.OutOfMemoryError: PermGen space
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) java.lang.reflect.InvocationTargetException
[error] Total time: 6 s, completed 8 Feb, 2014 6:13:54 PM
4. Waiting for source changes... (press enter to interrupt)
[error] Expected letter
[error] Expected symbol
[error] Expected '!'
[error] Expected '+'
[error] Expected '++'
[error] Expected ';'
[error] Expected end of input.
[error] Expected 'show'
[error] Expected '*'
[error] Expected '{'
[error] Expected project ID
[error] Expected configuration
[error] Expected key
[error] 9000
[error] ^
sbt appears to be exiting abnormally.
  The log file for this session is at /tmp/sbt7580663022166474466.log
java.lang.OutOfMemoryError: PermGen space
Error during sbt execution: java.lang.OutOfMemoryError: PermGen space
Exception in thread "Thread-125" java.lang.OutOfMemoryError: PermGen space

我认为你应该提及如何启动你的应用程序:你的环境(SBT等)和命令。 - yǝsʞǝla
2
这是在运行的JVM中重新编译的典型问题。你可能正在不断地测试和重新编译类? - nilskp
1
如果你正在测试阶段,应该以与生产环境相同的方式运行代码,即非交互式。请查看Play文档了解如何在stage模式下运行,或者更好的是,从dist命令创建的独立包中运行。 - millhouse
如果提供的答案解决了您的问题,请接受它以关闭问题。谢谢! - eliasah
5个回答

9

我遇到了同样的问题,所以我按照以下方式导出了SBT_OPTS

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

1
我认为这个不再起作用了。我收到一个有关选项PermSizeMaxPermSize已在8.0版本中被删除的HotSpot警告。 - Kat
我不确定。当我发布这个版本时,8.0版本还没有出来。 - eliasah
如果你要点踩,至少要有勇气说出为什么不对! - eliasah

3
通常这意味着你没有为JVM分配足够的内存,或者存在内存泄漏。看看人们如何处理这些问题:处理“java.lang.OutOfMemoryError:PermGen space”错误 或搜索非Play特定的错误:“java.lang.OutOfMemoryError: PermGen”。从您的日志中可以看出,您可能是从SBT或其他构建工具(如Maven)中运行的(“等待源更改…”)。为了帮助SBT防止内存泄漏,在启动时可以添加以下参数:
java -Xms128M -Xmx1200M -Xss20M -XX:MaxPermSize=1200m -XX:+CMSClassUnloadingEnabled -jar `dirname $0`/sbt-launch.jar "$@"

请注意类卸载命令行参数。总的来说,我注意到在SBT中运行的应用程序无论你做什么都会泄漏资源,但在生产环境中不会发生这种情况。你可以尝试在分叉JVM模式下运行以帮助SBT - 例如查看SBT-Revolver插件。如果您真的想知道应用程序如何使用内存以及它是否具有内存泄漏,请将其部署到类似Tomcat的容器中或运行jar等。您可以附加像jconsole这样的工具来观察内存使用情况。

2

您的代码会生成许多类。这些类存储在PermGen空间中,并且在Java 8之前永远不会被垃圾回收。您可以在运行JVM时使用-XXMaxPermSize选项来增加PermGen空间,例如:

-XX:MaxPermSize=512M

使用-Xmx-Xms(堆空间)不起作用,因为这是一个不同的空间。

您也可以使用Java 8 JVM,因为它不再使用PermGen。


1
你对Java 8所说的话同样适用于Java 7。 - Clint Eastwood

2

当您启动JVM时,请首先增加您的Perm Gen大小。

对您的代码进行分析,找出Perm Gen被消耗的原因。

查找从不释放引用、深度递归任务等集合。


-1

您可以使用JDK中的jconsole.exe来查看PermGen大小的增长趋势。也许它会在某些时间间隔内增加,这样您就更容易进行调试了。此外,尝试增加PermGen大小:增加permgen空间。 但如果问题出现在代码中,那么这种方法长期来看并不会有太大帮助...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接