This question already has an answer here:
Even with 7G of heap space, this will run out of memory.
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()
}
}
}
What is causing the problem, and how can it be avoided? The problem seems to be the call to bar
in the finalize method, but I don't understand why it would leak memory. I know that typical classes don't need to override finalize, but it is necessary in the real version of this code.
As I said in the comments, this is not at all a Scala-specific problem.
finalize
comes straight fromjava.lang.Object
. The problem is described very well by this answer, though I would hesitate to say that this question is an exact duplicate.The gist of it is that
finalize
needs to be called by something. But when you're creating 100 billion objects in rapid succession, they are getting created much faster than they can be finalized. The thread needs to be available to callfinalize
, but it isn't because it's too busy creating more objects.How can you fix it? You could start by not creating 100 billion instances of the same object in rapid succession. I know this is just a toy example, but in the real world you'll have to try to avoid allocating too many of these at the same time. And given this is not the actual code in question, it's harder to give better advice.