我面临着优化挑战。 我正在编写一个基于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计算机上运行。
我的假设:recordObjects
在getAnalytics
的调用完成后不会继续消耗内存。
这似乎是出现问题的唯一可能性。
我到底错在了什么?
答案 0 :(得分:1)
您可以尝试避免捕获对recordObjects
的引用:
object ElasticModel {
def getAnalytics(limit, startFrom): Future[(Boolean, 'Analytics')] = {
Future((
haveMore(),
getAnalysis(queryElastic.flatMap(result => new ElasticModel(result)))
))
}
}
但是,如果recordObjects
堆积起来,你不能拉出内存转储并检查吗?