Play Framework 1.2.5: 在Play框架中出现了OutOfMemoryError错误:Java堆空间

4
我在查询MongoDb的400k条记录时遇到了OutOfMemoryError错误。我有一个用户集合,大约有400k条记录。当我尝试检索所有用户(将其转储到弹性搜索中)时,会出现OutOfMemoryError错误。
我查看了这个链接,并在application.config中添加了jvm.memory=-Xms64m -Xmx1024m,但仍然出现相同的异常。
以下是我的堆栈跟踪 -
OutOfMemoryError occured : Java heap space

play.exceptions.JavaExecutionException: Java heap space
        at play.mvc.ActionInvoker.invoke(ActionInvoker.java:237)
        at Invocation.HTTP Request(Play!)
Caused by: java.lang.OutOfMemoryError: Java heap space
        at java.util.HashMap.<init>(HashMap.java:209)
        at java.util.LinkedHashMap.<init>(LinkedHashMap.java:181)
        at org.bson.BasicBSONObject.<init>(BasicBSONObject.java:45)
        at com.mongodb.BasicDBObject.<init>(BasicDBObject.java:42)
        at com.mongodb.DefaultDBCallback._create(DefaultDBCallback.java:124)
        at com.mongodb.DefaultDBCallback.create(DefaultDBCallback.java:87)
        at org.bson.BasicBSONCallback.objectStart(BasicBSONCallback.java:68)
        at com.mongodb.DefaultDBCallback.objectStart(DefaultDBCallback.java:63)
        at org.bson.BasicBSONCallback.objectStart(BasicBSONCallback.java:63)
        at org.bson.BasicBSONDecoder.decodeElement(BasicBSONDecoder.java:206)
        at org.bson.BasicBSONDecoder.decodeElement(BasicBSONDecoder.java:197)
        at org.bson.BasicBSONDecoder.decodeElement(BasicBSONDecoder.java:207)
        at org.bson.BasicBSONDecoder._decode(BasicBSONDecoder.java:80)
        at org.bson.BasicBSONDecoder.decode(BasicBSONDecoder.java:58)
        at com.mongodb.DefaultDBDecoder.decode(DefaultDBDecoder.java:56)
        at com.mongodb.Response.<init>(Response.java:66)
        at com.mongodb.DBPort.go(DBPort.java:128)
        at com.mongodb.DBPort.call(DBPort.java:79)
        at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:218)
        at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:189)
        at com.mongodb.DBApiLayer$Result._advance(DBApiLayer.java:452)
        at com.mongodb.DBApiLayer$Result.hasNext(DBApiLayer.java:418)
        at com.mongodb.DBCursor._hasNext(DBCursor.java:503)
        at com.mongodb.DBCursor.hasNext(DBCursor.java:523)
        at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1520)
        at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1332)
        at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1318)
        at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:504)
        at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:499)
        at com.salambc.service.ProfileService.getUsers(ProfileService.java:895)
        at controllers.Admin.index(Admin.java:56)

1
你可以分配多少内存?我会先尝试分配最大限制,看是否有所改善,然后再确定是否可以减少内存分配。 - Peter Lawrey
请注意,内存不足错误通常不是由其发生的代码片段引起的;它只是JVM耗尽内存的地方,很容易由其他原因引起。分析器可能会更深入地了解所有内存去向的情况。 - Gimby
我可以提供最多2GB的内存(因为我正在本地尝试,我的RAM大约是3GB)。 - mobizen
1
尝试将其减少到100,000条记录。如果有帮助,那么我们可以确定通过增加RAM来解决它。然后您应该考虑减少内存占用。 - Hari Menon
是的@Raze2dust,它可以完美地处理10万条记录。因此,我最终需要扩展JVM内存。 - mobizen
显示剩余2条评论
2个回答

4
请检查您的应用程序,因为内存中有许多大对象,所以您的内存不足。我遇到了同样的问题... 因为Play!中的所有变量/函数都是静态的,所以其中一些无法被GC释放。
请检查您使用TemplateLoader、RenderArgs、Jobs的方式,并尝试减少play pool和job pool(如果您设置了),最好是在4GB RAM下使用14个play pool(在我的情况下)。

1

由于将太多对象加载到内存中,您的内存已用尽。

在Java内存中加载太多对象不是一个好的实践。如果有很多用户尝试执行此用例,则无法进行扩展。

为您的Java进程允许更多的内存可以解决当前的错误,但不是长期的解决方案。

尝试考虑另一种设计,在其中可以通过持久存储器进行一些计算或通过小块数据(100或1000)加载数据,因为加载数据块会导致可预测的内存消耗。


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