内存不足:在wildfly和groovy/jasper中的metaspace

8
在我们的Wildfly 10应用服务器上,我们使用Groovy来处理JasperReports和其他类似系统。一段时间后,jvm(Java 8)会出现“Out of Memory:metaspace”错误。在某些旧的JBoss 4服务器上也会出现相同的问题,这些服务器使用PermGen(Java 6)。我们将JasperReports从3.7.2升级到6.3.1,但问题仍然存在。PermGen / Metaspace的大小足够大(最大512 MB)。
我们的其他不使用JasperReports和Groovy的应用程序没有这个问题。
经过一些研究,我发现这可能是类加载器中的内存泄漏(stackoverflow question)。看起来gc无法卸载从Groovy生成的类。
jaspersoft documentation上,他们写道,您应该将-XX:+UseConcMarkSweepGC-XX:+CMSClassUnloadingEnabled设置为VM参数以启用类卸载。

所以我们进行了更改,但问题仍然存在。 Java 8仍支持这些参数吗?如果不支持,是否有其他解决方案。 目前我们每晚都必须重新启动服务器以避免这个问题。


2
你尝试过为应用程序获取堆转储吗?这可能会提供一些关于正在分配的内容的见解。如果你寻找生成大量类的集合,你可能能够找到它们被分配的位置。 - Bruce Hamilton
2
你很可能存在类加载器泄漏。如果你有一个可以重现问题的好的测试环境,请在该环境中运行 jmap -clstats <jvm_pid> 命令。它会导致应用程序挂起,并需要几分钟的时间来运行(在我的应用程序中大约需要10分钟),但它会给你一个完整的类加载器列表及其状态。你很可能会看到大量死亡类型的加载器,如 "sun/reflect/DelegatingClassLoader" 和 "org/codehaus/groovy/runtime/callsite/CallSiteClassLoader"。 - Durandal
2
我会查看通过堆转储保留的类。这很可能是您的内存泄漏的原因。0.5 GB 应该足够大,但并不是非常巨大。如果您将其设置为 4 GB,您是否可以在重启之间运行一周? - Peter Lawrey
1
根据使用情况而定。大多数情况下,我们可以连续运行2天而无需重新启动,因此4GB应该可以持续一周。下周我将将metaspace更改为最大4GB,并在2或3天后进行堆转储。感谢迄今为止的帮助,当我分析完堆转储时,我会发布我的结果。 - Hauke Kern
1
正如Durandal所提到的,堆转储中有很多“sun/reflect/DelegatingClassLoader”和“org/codehaus/groovy/runtime/callsite/CallSiteClassLoader”的条目。看来groovy存在一些内存泄漏问题。我们将jasper报告的脚本引擎从groovy更改为java,将其他系统的脚本引擎更改为javascript,这解决了问题。感谢您的帮助。 - Hauke Kern
显示剩余4条评论
1个回答

0
正如Durandal在问题的评论中提到的那样,堆转储中有很多“sun/reflect/DelegatingClassLoader”和“org/codehaus/groovy/runtime/callsite/CallSiteClassLoader”的条目。看来groovy存在一些内存泄漏问题。我们将jasper报告的脚本引擎从groovy更改为java,将其他系统的脚本引擎更改为javascript。这解决了问题。感谢您的帮助。

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