Spray:PermGen在运行时期间部署的实例上的内存不足错误

时间:2015-01-05 17:59:34

标签: scala spray permgen

我有一个用大约60-70个端点编写的大型Spray API,我使用Java 7上的spray-can HTTP服务器运行它。在运行大量针对它的自动端到端测试时,我收到了java.lang.OutOfMemoryError:PermGen空格错误。

我设法通过强制卸载类来解决问题(使用-XX:+ CMSClassUnloadingEnabled),将Max PermGen大小增加到1024m并将线程堆栈大小设置为2m。但我担心我会掩饰我的问题。

我的问题是:

  • 我认为PermGen存储了类元数据。我可以理解在编译代码时如何耗尽PermGen空间。但是在这种情况下,我没有在机器上编译代码,如上所述,这个错误让我在运行应用程序时花了几分钟。为什么呢?

  • 我采取了正确的方法处理PermGen空间错误吗?是 推荐使用Spray-Can运行的应用程序的JVM标志?

  • 使用CMSClassUnloadingEnabled时,是否还需要在Java 7中使用UseConcMarkSweepGC?这个问题 (CMSPermGenSweepingEnabled vs CMSClassUnloadingEnabled) 似乎表明它适用于Java 6.

1 个答案:

答案 0 :(得分:1)

框架中的某些东西 - 或者无论如何都是代码 - 可能是动态创建类(代理等)。我建议您在运行一段时间后分析应用程序的堆转储,或者最好在崩溃OutOfMemoryError之后分析。关于如何创建转储的说明可以在我的this博客文章中找到。分析说明可能仅部分适用于您的情况。在找到正在填充PermGen的之后,我们可以尝试确定是否需要修复/阻止泄漏,或者应用程序是否只是大的。

是的,对于-XX:+ CMSClassUnloadingEnabled具有任何效果,您还需要使用-XX启用并发标记和扫描垃圾收集器:+ UseConcMarkSweepGC。然而,默认的GC(通常是较旧的JVM中的Parallell和较新的1.7+中的G1)默认情况下会进行类卸载,即使Parallell GC中似乎存在与此相关的错误。