【发布时间】:2016-04-05 08:15:01
【问题描述】:
我在实际项目中遇到过这个问题,并通过我的测试代码和分析器证明了这一点。我没有粘贴“tl;dr”代码,而是向您展示一张图片,然后对其进行描述。
简单地说,我使用Future.firstCompletedOf 从 2 个Futures 中得到一个结果,这两个都没有共享的东西,也不关心彼此。尽管如此,这是我要解决的问题,垃圾收集器无法回收第一个 Result 对象,直到两个 Futures 完成。
所以我真的很好奇这背后的机制。有人可以从较低的层次解释它,或者提供一些提示让我研究一下。
谢谢!
PS:是不是因为他们共享同一个ExecutionContext?
**更新**按要求粘贴测试代码
object Main extends App{
println("Test start")
val timeout = 30000
trait Result {
val id: Int
val str = "I'm short"
}
class BigObject(val id: Int) extends Result{
override val str = "really big str"
}
def guardian = Future({
Thread.sleep(timeout)
new Result { val id = 99999 }
})
def worker(i: Int) = Future({
Thread.sleep(100)
new BigObject(i)
})
for (i <- Range(1, 1000)){
println("round " + i)
Thread.sleep(20)
Future.firstCompletedOf(Seq(
guardian,
worker(i)
)).map( r => println("result" + r.id))
}
while (true){
Thread.sleep(2000)
}
}
【问题讨论】:
-
我很好奇你是如何设法证明“结果”不能被垃圾收集的,因为我会说相反,这可能很有趣。也许添加更多关于你如何验证的细节?
-
显示代码。几乎不可能说出没有它会发生什么。
-
其实这个问题是普遍性的,不依赖于具体的用例,所以很有可能在没有进一步细节的情况下回答。
-
@GiovanniCaporaletti 和 TheArchetypalPaul 感谢您的回复。稍后我将粘贴我的代码。然而,就像 Regis 所说的那样,非常简单明了,只有 2 个期货和一个分析器。我看到了这个对象并触发了一个 GC 事件,它仍然存在。在我的项目中,“结果”要大得多,而且当发生如此频繁时,它给了我一个 OutOfMemory 错误。
标签: scala concurrency garbage-collection jvm future