Scala:内存问题

时间:2015-08-03 15:35:16

标签: scala memory-management playframework jvm

我面临着优化挑战。 我正在编写一个基于Scala的服务,该服务使用Play Framework和ElasticSearch来分析索引中的大约200,000个文档。

现在,分析只能在所有文档上同时完成,我在ES之上有一个模型类,当作为列表传递给另一个方法时,在模型类上绘制分析。

现在,要立即获取200k文档并分析它们是不可能的,因为这超出了我们的限制。所以我做的是这个 - 从递归函数中:

def getOverallAnalytics(accumulatedAnalytics: Map[...], limit: Int, startFrom: Int) = {
    ElasticModel.getAnalytics(limit, startFrom).flatMap({
        case (hasMore, newAnalytics) => {
            val combinedAnalytics = combine(accumulatedAnalytics, newAnalytics)
            if (hasMore) getOverallAnalytics(combinedAnalytics, limit, startFrom + limit)
            else Future(newAccumulator)
        }
    })        
}

你有;

object ElasticModel {
    getAnalytics(limit, startFrom) = {
        val recordObjects = queryElastic.flatMap(result => new ElasticModel(result))
        Future((haveMore(), getAnalysis(recordObjects))) //
    }
}

这样的效果。现在,包含分析的地图有一组非常小的键。鉴于此,人们不会期望看到

java.lang.OutOfMemoryError:
Unable to create new native thread

在16GB RAM计算机上运行。

我的假设:recordObjectsgetAnalytics的调用完成后不会继续消耗内存。

这似乎是出现问题的唯一可能性。

我到底错在了什么?

1 个答案:

答案 0 :(得分:1)

您可以尝试避免捕获对recordObjects的引用:

object ElasticModel {
    def getAnalytics(limit, startFrom): Future[(Boolean, 'Analytics')] = {
        Future((
          haveMore(), 
          getAnalysis(queryElastic.flatMap(result => new ElasticModel(result)))
        ))
    }
}

但是,如果recordObjects堆积起来,你不能拉出内存转储并检查吗?