我们使用flatMap (in表示理解)来链接一长串可能失败事情。因此,我们有很多方法返回类似Either的内容,如下所示:
// 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中有没有什么选项可以做到这一点?如果没有,应该如何重构代码以使其成为可能?
发布于 2019-12-17 00:10:24
我做了一些测试,就像System.gc()允许的那样糟糕。我仍然很想知道,有scalac和/或jvm规范的内部知识的人,预期的行为是什么。
下面的代码在` `scalac 2.12下运行,具有以下选项:
-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
t3.中被释放
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
}
}https://stackoverflow.com/questions/59358642
复制相似问题