Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do constructor arguments get GC'ed?

I am using a system which needs to initialize many objects using transactions, and for reasons beyond the scope of this question these transactions must be passed into the constructors. Like this:

trait Mutable

class Txn(i: Int) {
  def newID(implicit m: Mutable): Int = i
  override def finalize(): Unit = println("Finalised " + i)
}

class User(t0: Txn) extends Mutable {
  val id = t0.newID(this)
}

Now I am fearing there is a problem with garbage collecting the transactions:

val u = new User(new Txn(1234))
System.gc()  // hmmm, nothing seems to happen?

So my question is: Does the t0 constructor argument ever get garbage collected, or do I create a memory leak here? In an equivalent Java code, I guess I'd have something like this:

public class User implements Mutable {
    final int id;
    public User(Txn t0) {
        id = t0.newID(this);
    }
}

and I am sure t0 is collected. But is this true in the Scala case?

If not, how can I ensure t0 is garbage collected? Remember that I must pass in the transaction as a constructor argument, because the User class implements some traits which must be passed into Txn's methods, thus those methods (like newID) cannot be called before constructing User.

I have tried before to construct everything that uses the transaction outside of the user object, with tons of lazy interdependent vals, but that was really messy. For example, this, which is already halfway unreadable, produces a stack overflow:

trait User extends Mutable { def id: Int }

def newUser(implicit tx: Txn): User = {
  lazy val _id: Int = tx.newID(u)
  lazy val u  = new User { val id: Int = _id } // oops, should be lazy val id!
  u
}

val u = newUser(new Txn(1234))

You can imagine that it really sucks that the compiler won't spot the problem with the missing lazy val here, so I would definitely prefer the constructor arg variant.

like image 888
0__ Avatar asked Dec 27 '11 09:12

0__


People also ask

Which objects are eligible for garbage collection?

An object is eligible to be garbage collected if its reference variable is lost from the program during execution. Sometimes they are also called unreachable objects. What is reference of an object? The new operator dynamically allocates memory for an object and returns a reference to it.

How does an object become eligible for garbage collection can this be manually done?

An object is eligible for garbage collection when there are no more references to that object. References that are held in a variable are usually dropped when the variable goes out of scope. Or, you can explicitly drop an object reference by setting the variable to the special value null.

How can we prevent object from collecting garbage in Java?

We have three ways to achieve same - 1) Increasing the Heap -Eden space size . 2) Create Singleton class with Static reference . 3) Override finalize() method and never let that object dereference.

How can we stop garbage collection?

You can't force garbage collection in Java. There are some strategies you can use to get the Java virtual machine to prioritize the task, but the indeterminate nature of garbage collection means the process can't be forced. Similarly, you can't stop Java garbage collection from happening, either.


1 Answers

Constructor arguments get GCed if they are not used beyond the static initializer. You can check the bytecode and verify that no reference to the constructor argument is preserved in this case.

class WillNotStore(s: Seq[Int]) { val length = s.length }

public WillNotStore(scala.collection.Seq);
  Code:
   0:   aload_0
   1:   invokespecial   #18; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   aload_1
   6:   invokeinterface #22,  1; //InterfaceMethod scala/collection/SeqLike.length:()I
   11:  putfield    #11; //Field length:I
   14:  return

Note that the argument is loaded (line 5) and a method is called on it (line 6), but only the answer is stored (line 11) before the constructor quits (line 14).

like image 77
Rex Kerr Avatar answered Sep 19 '22 03:09

Rex Kerr