使用Quartz调试Groovy / Grails应用程序中的堆空间问题

我在Groovy / Grails中创建了一个小应用程序,它使用Quartz每10秒执行一次小作业.现在我遇到的问题是,运行几个小时后,应用程序崩溃了一个org.quartz.JobExecutionException:
java.lang.OutOfMemoryError:
Java堆空间[请参阅嵌套异常:java.lang.OutOfMemoryError:Java堆空间].

现在我试图找到使用Eclipse Memory Analyzer的问题的原因之一.通过找到“问题嫌疑人”,分析仪显示了这个结果:

Problem Suspect 1

3,926 instances of "groovy.lang.ExpandoMetaClass",
loaded by "org.codehaus.groovy.grails.cli.support.GrailsRootLoader @ 0x122e88b98" 
occupy 95,746,168 (33.69%) bytes. 

Keywords
org.codehaus.groovy.grails.cli.support.GrailsRootLoader @ 0x122e88b98
groovy.lang.ExpandoMetaClass

--    

Problem Suspect 2

1,010 instances of "com.mongodb.DBApiLayer",
loaded by "org.codehaus.groovy.grails.cli.support.GrailsRootLoader @ 0x122e88b98" 
occupy 56,522,416 (19.89%) bytes.
These instances are referenced from one instance of
"org.codehaus.groovy.util.AbstractConcurrentMapBase$Segment[]", loaded by 
"org.codehaus.groovy.grails.cli.support.GrailsRootLoader @ 0x122e88b98"

Keywords
org.codehaus.groovy.grails.cli.support.GrailsRootLoader @ 0x122e88b98
org.codehaus.groovy.util.AbstractConcurrentMapBase$Segment[]
com.mongodb.DBApiLayer

在Groovy(和Grails)应用程序中拥有那么多ExpandoMetaClass实例是否正常,或者这可能是我介绍的问题?

关于MongoDB:应用程序使用GORM从数据库读取和写入许多小项目,并直接使用Gmongo.但是,我已经检查了所有连接,并且在一段时间后它们正确关闭.活动线程的大概数量约为40.所以我认为DB层不应该是问题.但是,它需要很大一部分堆.有什么想法吗?

有什么建议?

最佳答案 这实际上可能是GMongo驱动程序的问题.在
a thread in the gmongo Github中,具有类似环境的用户具有非常相似的问题.

Gmongo是grails mongo插件(see this source)使用的驱动程序.

如果可以的话,尝试使用MongoDB驱动程序本身,而不是Gmongo或它依赖的Grails插件.

作为一种解决方法,并且作为隔离问题的一种方法,您可以尝试增加堆大小;如果您目前正在人为地缩小堆大小,这尤其是一个好主意.

export GRAILS_OPTS="-Xmx1G -Xms256m -XX:MaxPermSize=256m"
grails run-app

如果内存消耗在某一点处稳定,则可能会停止出现内存不足错误.如果没有,那么增加堆大小应该比延迟不可避免的更多.跟踪相对于堆大小的崩溃时间对于向gmongo开发团队报告是非常有用的.

点赞