当前位置: 首页 > 知识库问答 >
问题:

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

爱花蜂
2023-03-14

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

现在,我正试图使用Eclipse内存分析器来找出这个问题的原因。通过查找“问题嫌疑人”,分析人员显示了以下结果:

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层不应该是问题所在。尽管如此,它还是占据了很大一部分。有什么想法吗?

有什么建议吗?

共有2个答案

逄念
2023-03-14

用户@jonnybot建议问题可能是由GMongo引起的,事实上他是对的。我开始与GMongo的创建者进行讨论,在讨论中我创建了一个小应用程序,它每秒向MongoDB集合中插入一些东西,以便能够复制问题。应用程序显示大量内存泄漏

class MemoryJob {
    def concurrent = false
    static triggers = {
        simple startDelay: 5000, repeatInterval: 1000
    }
    def execute() {
        def mongoUrl = "mongodb://localhost:27017"
        def mongo = new GMongo(new MongoURI(mongoUrl))
        def db = mongo.getDB("memory")
        println new Date()
        db.getCollection("test").insert(['date':new Date()])
        mongo.close()
    }
}

然后,GMongo的作者建议重用数据库连接,而不是在每次请求时创建新的连接。例子:

class MemoryJob {
    def concurrent = false
    static triggers = {
        simple startDelay: 5000, repeatInterval: 200
    }
    static mongoUrl = "mongodb://localhost:27017"
    static mongo = new GMongo(new MongoURI(mongoUrl))
    static db = mongo.getDB("memory");
    def execute() {
        println new Date()
        db.getCollection("test").insert(['date':new Date()])
    }
}

事实上,这解决了我遭受的内存泄漏问题。

总结:不要对每个请求都创建MongoDB连接,而是重用单个连接。尽管GMongo中似乎存在内存泄漏,但可以通过重用连接来避免。

希望这能帮助某人节省一些时间。

宦博超
2023-03-14

这实际上可能是GMongo司机的问题。gmongo Github中有一个线程,具有类似环境的用户有一个非常相似的问题。

Gmongo是grails mongo插件使用的驱动程序(请参阅此源代码)。

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

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

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

如果内存消耗在某一点趋于平稳,那么您可能会停止出现内存不足错误。否则,增加堆大小只会延迟不可避免的事情。向gmongo开发团队报告相对于堆大小的崩溃时间将是一件非常有用的事情。

 类似资料:
  • 我使用的是Spark独立单机,128G内存,32核。以下是我认为与我的问题相关的设置: 我有一个Spark应用程序,其中有1000个设备的循环。对于每个循环(设备),它准备特征向量,然后调用MLLib的k-Means。在循环的第25次到第30次迭代(处理第25次到第30次设备)时,它遇到了错误“Java.lang.OutOfMemoryError:Java堆空间”。 我试着从0.7到0.35进行记

  • 当我调试我的应用程序时,它会显示一个错误,如BUILD FAILED 总时间:1分钟41.485秒执行任务:[: app: GenerateDebugSSource,: app: GenerateDebugAndroidTestSSource,: app: mockableAndroidJar,: app: preareDebugUnitTestDependency] 失败:构建失败,但有例外。

  • 我在用grails跑步https://github.com/Netflix/ice但我只是无法让服务器运行,出现以下错误: |错误2014-06-06 14:52:55978[localhost-startStop-1]错误上下文。GrailsContextLoader-初始化应用程序时出错:com。谷歌。常见的util。同时发生的ExecutionError:java。lang.OutOfMem

  • 如果这个问题太幼稚,我很抱歉,我希望作业被安排成一个一个地执行,而不是并行地执行,它只执行一次。 在文档中,@disallowConcurrentExecution是 null PS:我不知道会安排哪些工作。因此,如果作业已经在运行,我需要一些方法来动态链接作业。

  • 问题内容: 实际上,我有两个有关Android错误的相关问题。我发布了一个应用程序的更新,该应用程序以前可以正常运行,并且可以在Nexus One,G1和模拟器上以当前版本运行。但是,自从上次更新以来,我通过Android市场控制台收到了很多错误日志,并且无法重现该错误。该应用程序非常简单,只有两个活动,因此手动测试该应用程序应该非常容易。但是,在发布之前,经常会发现一些我找不到的错误。 所以第一

  • 问题内容: 有很多问题问这个问题或类似的问题。 它们都给出了必须执行的命令,我不知道该在哪里编写此命令。我想为我的tomcat应用程序永久增加堆空间。 我读了这页 http://javahowto.blogspot.com/2006/06/6-common-errors-in- setting-java-heap.html ,它在Tomcat部分下说 停止Tomcat服务器,设置环境变量CATAL