gpt4 book ai didi

scala - scala future 的垃圾收集

转载 作者:行者123 更新时间:2023-12-02 02:10:59 25 4
gpt4 key购买 nike

我有一堆要并行处理的 xml 文件。我使用 future 的 scala 代码 (2.9.2) 开始时运行良好,但最终耗尽了我机器上 32G 内存的近 100%。当我按顺序执行此操作时不会发生这种情况,所以我猜测在使用 scala futures 时垃圾收集有问题。

这是我的代码的精简版。谁能告诉我哪里出了问题?

val filenameGroups = someStringListOfFilepaths.grouped(1000).toStream
val tasks = filenameGroups.map {
fg =>
scala.actors.Futures.future {
val parser = new nu.xom.Builder() // I'm using nu.xom. Not sure it matters.
fg.map {
path => {
val doc = parser.build(new java.io.File(path))
val result = doc.query(some xpath query)
result
}
}.toList
}
}

val pairs = tasks.par.flatMap(_.apply)

预计到达时间:好的,我解决了这个问题,但我仍然不知道为什么这会产生影响。

我提取了内部循环中的大部分代码,然后重新运行它。并从 future 中取出解析器实例化。内存使用率现在稳定在 17% 的不错水平。有人知道为什么这会有所作为吗?

这是我所做的简化版本:

def process(arglist...) = yada

val tasks = filenameGroups.map {
fg =>
val parser = new nu.xom.Builder()
scala.actors.Futures.future {
process(fg, parser)
}
}

val pairs = tasks.par.flatMap(_.apply)

最佳答案

Futures 无法真正预测您需要多少个线程或您的计算将占用多少内存,因此通常您有责任将适当的序列化计算放入适度数量的 futures 中。特别是,如果您使用的是 8 核机器,您可能不想分组比 someStringListOfFilepaths.length/8 小得多(如果您的文件太大以至于您不能拥有 8一次在内存中)。您可以使用检查核心数量的标准 Java 技巧,covered on SO和许多其他地方,如果你想在每台机器上扩展它而不必考虑它。 (在这种情况下,可能还需要检查 Runtime.getRuntime.maxMemory,以防万一您使用的机器有很多内核但 RAM 不多(或者分配给 VM 的内存不多)。)

(顺便说一句,在您的最小示例中,既有懒惰又有 future ,但懒惰对您没有任何作用。 future 在创建时已经没有运行,因此延迟 future 的实例化可能对您没有任何帮助。 )

另请注意,如果您有 200k 个文件,最终将得到 200k 个结果,并且根据结果的大小,这可能会占用大量内存。可能不是 32G,但谁知道文件中有什么?

关于scala - scala future 的垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12921619/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com