Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the memory management of closures in Scala work?

Scala allows closure like

def newCounter = {
  var a=0
  () => {a+=1;a}
}

which defines a function that on every call returns a new independent counter function starting at 1:

scala> val counter1 = newCounter
counter1: () => Int = <function0>

scala> counter1()
res0: Int = 1

scala> counter1()
res1: Int = 2

scala> val counter2 = newCounter
counter2: () => Int = <function0>

scala> counter2()
res2: Int = 1

scala> counter1()
res3: Int = 3

This is quite impressive as usually a would be a representative of a memory address on the stack frame of newCounter. I've just read the closure chapter of "Programming in Scala" and it only has the following to say on that matter (p. 155):

The Scala compiler rearranges things in cases like this so that the captured parameter lives out on the heap, instead of the stack, and thus can outlive the method call that created it. This rearrangement is all taken care of automatically, so you don't have to worry about it.

Can anyone elaborate on how this works on byte code level? Is the access similar to a member variable of a class with all the associated synchronization and performance implications?

like image 857
Perseids Avatar asked Jun 16 '13 14:06

Perseids


People also ask

Where are closures stored in memory?

So. With this in mind, the answer is that variables in a closure are stored in the stack and heap.

What is the use of closures in Scala?

A closure is a function, whose return value depends on the value of one or more variables declared outside this function. The following piece of code with anonymous function. There are two free variables in multiplier: i and factor. One of them, i, is a formal parameter to the function.

What are closures in spark?

Summing up, closure is those variables and methods which must be visible for the executor to perform its computations on the RDD. This closure is serialized and sent to each executor. Understanding closure is important to avoid any unexpected behaviour of the code.

What is a free variable in Scala?

A free variable of an expression is a variable that's used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x, y) , both variables x and y are used, but only y is a free variable, because it is not defined inside the expression.


1 Answers

You could use scalac -Xprint:lambdalift <scala-file-name> to investigate this.

Your code is actually something like this:

def newCounter = {
  val a: runtime.IntRef = new runtime.IntRef(0);
  new Function0 {
    private[this] val a$1 = a
    def apply() = {
      a$1.elem = a$1.elem + 1
      a$1.elem
    }
  }
}

There is a wrapper for any var used by lambda. Other vars (not used in closures) are common locale variables.

The link to this wrapper is stored as field in the instance of function.

lambdalift in -Xprint:lambdalift is the compiler phase. You can get all phases with -Xshow-phases. You could use phase number instead of name, it's useful when you are not sure which phase you need.

like image 145
senia Avatar answered Nov 24 '22 12:11

senia