Troubleshooting "Out of Memory Error: Metaspace" in Play for Scala

Troubleshooting "Out of Memory Error: Metaspace" in Play for Scala

在 Play for Scala (2.5.x) 的开发模式下工作时,在更改代码和热部署大约三个小时后,Play 挂起并出现错误 java.lang.OutOfMemoryError: Metaspace.

经过一些研究,问题似乎是应用程序实例化了 Play 不知道的 Java 对象(例如工厂和连接),并且当 Play 重新启动时这些对象留在内存中导致泄漏。解决方案是按照 here 解释的那样在 Play 关闭时清理组件,或者在使用后销毁它们。

问题是我清理了所有这些对象,但仍然得到 OutOfMemoryError。我尝试使用 Java 的 jconsole 来找出是什么 类 造成了泄漏以及它们占用了多少内存,但找不到太多。任何想法如何处理这种情况?我不想在不知道发生了什么的情况下简单地增加内存。

PS: 这好像是一个普遍的问题,如果Play本身能提供检测问题的工具就好了。

不幸的是,这个问题目前看来是不可避免的。尽管在 Play 2.6 中它变得更好,但我仍然 运行 喜欢它。

这与组件未清理无关,元空间是加载 类 的地方。 Play(动态地)在编译时创建了很多 类(例如匿名 类),每个 类 添加到元空间,最终被填满。

我的建议是只增加 -XX:MaxMetaspaceSize 直到你可以工作几个小时而没有这个例外。然后,偶尔重新启动 sbt。我目前使用 500 MB,这似乎没问题(SBT 启动器通常是 128MB):

sbt -J-XX:MaxMetaspaceSize=500m

这在生产中通常没有问题,因为您加载了固定数量的 类(在生产中没有编译)。