Scala Future `.onComplete` функция отбрасывается после вызова? - PullRequest
3 голосов
/ 30 июня 2019

Тела функций передаются в Future.onComplete(), а их замыкания сбрасываются и, таким образом, собирается ли мусор после их вызова?

Я спрашиваю, потому что пишу неограниченную последовательность Future экземпляров.Каждый Future имеет .onComplete { case Failure(t)...}, который ссылается на предыдущее известное значение из предыдущего Future.Чего я хочу избежать, так это полной истории всех Future результатов, хранящихся в памяти JVM из-за ссылок в закрывающих телах.

Возможно, Scala более умный, чем этот, но скипмирует код, связанный с контекстами выполнения.и фьючерсы мало что дают.

Спасибо.

1 Ответ

3 голосов
/ 30 июня 2019

Класс, который обычно реализует Future и на который вы хотите посмотреть, является DefaultPromise.

Содержит изменяемое состояние, которое обновляется по завершении Future.

  • Если вы звоните onComplete, и он уже завершен, он просто сразу же планирует ваш обратный вызов с результатом. Обратный вызов нигде не записан.
  • Если вы позвоните onComplete, пока результат еще не доступен, обратный вызов добавляется в список «слушателей».
  • Когда результат становится доступным (кто-то вызывает complete по обещанию), тогда все слушатели планируются для запуска с этим результатом, и список слушателей удаляется (внутреннее состояние изменяется на «завершено с этим результатом»)

Это означает, что ваша цепочка обратных вызовов строится только до тех пор, пока «восходящее будущее» не будет завершено. После этого все решается и собирается.


«Список слушателей» выше - это немного упрощение. Особое внимание уделяется тому, чтобы эти слушатели не заканчивали ссылками друг на друга, в частности, чтобы разорвать циклы ссылок, которые не позволили бы сбору мусора работать при рекурсивном построении фьючерсов. Очевидно, это было действительно проблемой в более ранних версиях.

Проблема утечек решается путем автоматического разрыва этих цепочек обещаний, чтобы обещания не ссылались друг на друга в длинной цепочке. это позволяет каждому обещанию быть собраны индивидуально. Идея состоит в том, чтобы "сгладить" цепочка обещаний, так что вместо каждого обещания, указывающего на его сосед, вместо этого они прямо указывают на обещание в корне цепь. Это означает, что ссылка только на корневое обещание, и все другие обещания доступны для сбора мусора, как только их нет больше ссылается на код пользователя.

...