【问题标题】:How do I mitigate memory leaks when recursively calling a function inside a Future[T]?在 Future[T] 中递归调用函数时如何减轻内存泄漏?
【发布时间】:2015-07-14 09:57:42
【问题描述】:

这个问题的灵感来自早期 Stackoverflow article 中关于同一主题的一些 cmets,也受到我正在编写的一些代码的启发。鉴于其中包含的示例,我有点相信这种模式是尾递归的。如果是这种情况,我如何减轻由累积期货造成的内存泄漏,这些期货的底层线程从未加入产生它们的 ForkJoinPool?

import com.ning.http.client.AsyncHttpClientConfig.Builder
import play.api.libs.iteratee.Iteratee
import play.api.libs.iteratee.Execution.Implicits.defaultExecutionContext
import play.api.libs.ws.ning.NingWSClient
import scala.util.{Success,Failure}

object Client {
 val client = new NingWSClient(new Builder().build())
 def print = Iteratee.foreach { chunk: Array[Byte] => println(new String(chunk)) }

 def main(args: Array[String]) {
   connect()
   def connect(): Unit = {
     val consumer = client.url("http://streaming.resource.com")
     consumer.get(_ => print).onComplete {
       case Success(s) => println("Success")
       case Failure(f) => println("Recursive retry"); connect()
     }
   }
 }
}

在我分享的示例中,get[A](...) 方法返回一个Future[Iteratee[Array[Byte],A]]。上述文章的作者我已经包含了“scala.concurrent Futures 不会被合并”的评论,一旦它们返回,但 Twitter 的 futures 是如何管理这个的。但是,我使用的是 PlayFramework 实现,它使用标准 Scala 2.1X 库提供的期货。

你们中是否有人有证据支持或驳回这些说法?我的代码会造成内存泄漏吗?

【问题讨论】:

    标签: scala recursion concurrency playframework tail-recursion


    【解决方案1】:

    您链接的问题(在评论中,而不是问题或答案中)是指flatMap 发生的内存泄漏。你的代码没有使用flatMap,所以我认为你不会遇到任何问题,因为你只是通过回调有条件地执行另一个Future,而不关心之前的。

    无论哪种方式,这都无关紧要,因为此问题已在 2.10.3 中修复。有关更多信息,请参阅问题 SI-7336 和修复它的 pull request

    【讨论】:

      【解决方案2】:

      虽然您的调用不会遭受常规递归调用的堆栈溢出危险,但它也不是尾递归。 connect() 的退出语句是 onComplete,它只是让 connect() 退出并释放其堆栈。对 connect() 的“递归”调用实际上是在未来完成时作为延续发生,因此不是实际的递归。

      警告:如果 get 实际上总是返回 Future.successful(可能在单元测试中),那么 get 可能会遭受堆栈溢出,因为 @987654328 @case 想在onComplete 退出之前立即触发。我没有对此进行测试,它可能会发生也可能不会发生,具体取决于ExecutionContext 的属性。

      【讨论】:

        猜你喜欢
        • 2012-10-31
        • 2015-07-27
        • 2013-06-15
        • 2021-07-11
        • 1970-01-01
        • 2016-03-15
        • 2017-05-09
        • 1970-01-01
        • 2014-12-21
        相关资源
        最近更新 更多