2015-05-11 109 views
1

即使有7G的堆空間,這也會耗盡內存。這個奇怪的Scala內存泄漏的原因是什麼?

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,但是在這個代碼的真實版本中是必需的。

+6

它也會發生在Java中:http://stackoverflow.com/a/8355147/2292812你正在使終結器比後臺線程可以調用它們更快,所以它們堆積起來,不會得到GC'編輯。 –

回答

2

正如我在評論中所說,這完全不是Scala特有的問題。 finalize直接來自java.lang.Object。這個問題很好地描述了this answer,雖然我會毫不猶豫地說這個問題是完全重複的。

它的要點是finalize需要被某些東西調用。但是,當你連續快速創建1000億個物體時,它們的創建速度要比它們的最終速度快得多。該線程需要可用於調用finalize,但這不是因爲它太忙而無法創建更多的對象。

你怎麼解決它?您可以先不快速連續創建1000億個同一個對象的實例。我知道這只是一個玩具的例子,但在現實世界中,你必須儘量避免同時分配太多這樣的東西。鑑於這不是實際的代碼,更難給出更好的建議。