Я столкнулся с этой проблемой в своем реальном проекте и подтвердил свой тестовый код и профайлер. Вместо того, чтобы вставлять код «tl; dr», я показываю вам фотографию, а затем описываю ее. О Future.firstCompletedOf и Механизм сбора мусора
Проще говоря, я использую Future.firstCompletedOf
, чтобы получить результат от 2 Future
с, оба из которых не имеют общих вещей, и не заботятся друг о друге. Несмотря на то, что вопрос, который я хочу рассмотреть, Сборщик мусора не может перерабатывать первый объект Result
, пока оба из Future
s не закончили.
Так что мне действительно интересно, какой механизм стоит за этим. Может кто-нибудь объяснить это с более низкого уровня или дать мне какой-то намек.
Спасибо!
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)
}
}
Мне любопытно, как вам удалось доказать, что «результат» не может быть собран из мусора, потому что я бы сказал наоборот, это может быть интересно.Может быть, добавьте более подробную информацию о том, как вы это подтвердили? –
Показать код. Практически невозможно сказать, что может произойти без него. –
На самом деле проблема является общей и не зависит от конкретного варианта использования, поэтому можно ответить без дальнейших подробностей. –