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
这在生产中通常没有问题,因为您加载了固定数量的 类(在生产中没有编译)。
在 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
这在生产中通常没有问题,因为您加载了固定数量的 类(在生产中没有编译)。