首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Scala中,在flatMap期间,不再被引用的对象可以被垃圾回收吗?

在Scala中,在flatMap期间,不再被引用的对象可以被垃圾回收吗?
EN

Stack Overflow用户
提问于 2019-12-16 22:27:04
回答 1查看 157关注 0票数 1

我们使用flatMap (in表示理解)来链接一长串可能失败事情。因此,我们有很多方法返回类似Either的内容,如下所示:

代码语言:javascript
复制
// point-0
for {
  // point-1
  a <- createBigObject
  // point-2
  b <- doSomeTransformationOn(a)
  // point-3
  c <- sameBWichCanBeLong
} yield {
  // point-4
  c
}
// point-5

在我们的例子中,a非常大。我们不想在不必要的情况下保留它。

我的问题是:a可以在point-3中被垃圾回收吗(因为在那之后它就不再被引用了)?如果不是,scalac中有没有什么选项可以做到这一点?如果没有,应该如何重构代码以使其成为可能?

EN

回答 1

Stack Overflow用户

发布于 2019-12-17 00:10:24

我做了一些测试,就像System.gc()允许的那样糟糕。我仍然很想知道,有scalac和/或jvm规范的内部知识的人,预期的行为是什么。

下面的代码在` `scalac 2.12下运行,具有以下选项:

代码语言:javascript
复制
-target:jvm-1.8
-Ypartial-unification
-Xcheckinit
-Xfuture
-Xlint:_,-nullary-unit,-missing-interpolator
-Yno-adapted-args
-Ywarn-dead-code
-Ywarn-extra-implicit
-Ywarn-inaccessible
-Ywarn-infer-any
-Ywarn-nullary-override
-Ywarn-numeric-widen
-Ywarn-unused:imports
-Ywarn-unused:locals
-Ywarn-unused:privates

编辑:添加-opt:_导致相同的结果。

test-0似乎表明对象在整个for

  • test-1期间没有被释放,这似乎表明一个很好的小范围允许对象被释放是如预期的那样,但是

  • -3很奇怪:我不知道为什么对象不能在t3.

中被释放

代码语言:javascript
复制
package com.normation

import scala.concurrent.Future
object CheckMemoryReleaseFlatMap {


  def getFreeMem = (Runtime.getRuntime().freeMemory() / (1024*1024)).toString + " MB"
  def doGC = {
    System.gc()
    System.runFinalization()
  }

  // this array is 200MB
  def newBigArray() = Array.fill(50 * 1024)(Array.fill(1024)("x"))

  implicit val ec = scala.concurrent.ExecutionContext.global

  /*
   * Configuring jvm with -Xmx500M -Xms500M
   */

  def test0(): Unit = {
    Future {
      doGC
      println("t0: " + getFreeMem)                   // t0: 493 MB
      doGC
      for {
        a <- Some(newBigArray())
        _ = doGC
        _ =  println("t1: " + getFreeMem)            // t1: 292 MB
        _ = doGC
        b <- Some(newBigArray())
        _ = doGC
        _ =  println("t2: " + getFreeMem)            // t2:  91 MB
        _ = doGC
      } yield {
        doGC
        Thread.sleep(2000)
        println("t3: " + getFreeMem)                 // t3:  91 MB
        Unit
      }
    }

    Thread.sleep(5000)
    doGC
    println("t4: " + getFreeMem)                     // t4: 493 MB

  }

  def test1(): Unit = {
    Future {
      doGC
      println("t0: " + getFreeMem)                   // t4: 493 MB
      doGC
      for {
        x <- for {
                a <- Some(newBigArray())
                _ = doGC
                _ =  println("t1: " + getFreeMem)    // t1: 292 MB
                _ = doGC
                b <- Some(newBigArray())
             } yield b
        _ = doGC
        _ =  println("t2: " + getFreeMem)            // t2: 292 MB
        _ = doGC
      } yield {
        doGC
        Thread.sleep(2000)
        println("t3: " + getFreeMem)                 // t3: 292 MB
        Unit
      }
    }

    Thread.sleep(5000)
    doGC
    println("t4: " + getFreeMem)                     // t4: 493 MB
  }

  def test2(): Unit = {
    doGC
    println("t0: " + getFreeMem)                     // t0: 493 MB
    doGC
    val a = Some(newBigArray())
    doGC
    println("t1: " + getFreeMem)                     // t1: 292 MB
    doGC
    val b = Some(newBigArray())
    doGC
    println("t2: " + getFreeMem)                     // t2:  91 MB
  }

  def test3(): Unit = {
    doGC
    println("t0: " + getFreeMem)                     // t0: 493 MB
    doGC

    {
      val a = Some(newBigArray())
      doGC
      println("t1: " + getFreeMem)                   // t1: 292 MB
      doGC
      val b = Some(newBigArray())
      doGC
      println("t2: " + getFreeMem)                   // t2:  91 MB
    }
    doGC
    println("t3: " + getFreeMem)                     // t3:  91 MB  => ????
  }

  def main(args: Array[String]): Unit = {
    println("======= test 0 ========")
    test0
    doGC
    println("======= test 1 ========")
    test1
    doGC
    println("======= test 2 ========")
    test2
    doGC
    println("======= test 3 ========")
    test3
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59358642

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档