这种奇怪的 Scala 内存泄漏的原因是什么?

What is the cause of this strange Scala memory leak?

即使有 7G 堆 space,这也会 运行 内存不足。

import scala.collection.mutable.Set

class Foo() {
  val anEmptySet: Set[Int] = Set()
  def bar(ints: Traversable[Int]): Unit = {}
  override def finalize() {
    bar(anEmptySet)
    super.finalize()
  }

}

object FooTest {
  def main(args: Array[String]): Unit = {
    for (i <- 0 to 100000000) {
      val f = new Foo()
    }
  }
}

是什么导致了问题,如何避免?问题好像是在finalize方法中调用了bar,但是我不明白为什么会泄漏内存。我知道典型的 类 不需要重写 finalize,但在这段代码的真实版本中是必需的。

正如我在评论中所说,这根本不是 Scala 特有的问题。 finalize 直接来自 java.lang.Objectthis answer 很好地描述了这个问题,但我会毫不犹豫地说这个问题是完全重复的。

其要点是finalize需要被某些东西调用。但是,当您快速连续地创建 1000 亿个对象时,它们的创建速度要比最终确定的速度快得多。线程需要可用才能调用 finalize,但这并不是因为它忙于创建更多对象。

如何解决?您可以从不快速连续创建同一对象的 1000 亿个实例开始。我知道这只是一个玩具示例,但在现实世界中,您必须尽量避免同时分配太多此类内容。鉴于这不是有问题的实际代码,因此很难提供更好的建议。