I'm a C++ programmer entering the world of Java. And I cannot get rid of the bad feeling of having to let the Java garbage collector do my cleaning.
How, for example, will this code behave in Java?
public void myFunction() {
myObject object = new myObject();
object.doSomething();
}
Will the local variable object be deleted when myFunction() exits?
Do I have to set object to null before exiting, or will it be out of scope and be deleted by the GC? Or, at worst, will it leak like it would in C++?
It will go out of scope. In Java, when no-one is pointing to an object anymore, it will be garbage collected or at least it will be available for garbage collection. No need to set it to null here. Sometimes setting an object reference to null is needed if your object will live on in you App, but a reference it holds needs to be garbage collected. In this case you are choosing to release the reference.
It will be garbage collected at some point after it's no longer used. I believe in current implementations of Java it will actually persist until the end of the method, whereas the garbage collector in .NET is more aggressive. (I don't know whether there are any guarantees even in Java. Normally you'd only want the local variable to persist beyond its last possible read when you're debugging.)
But no, you don't need to set the variable to null, and doing so would harm readability.
It's unlikely that the object will garbage collected immediately after the method exits; it's up to when the GC runs... and of course if anything else holds onto a reference to the object, it may not be eligible for garbage collection anyway. Don't forget that the value of the variable is just a reference, not the object itself. (That may take a while to get used to coming from C++.)
GC does the job at least when memory limit approaches, since any object referenced by out-of-scope variables can be garbage collected, but there is an unexpected behavior of out-of-scope local variables of the last exited block.
To look under the hood, let us compare :
somethingRunOutOfMemory()
becausemyTooBigList
were not GCable, despite not in scope anymore and more memory was claimed, unlike the following :Affectation of
fake
moves the stack pointer back and letmyTooBigList
GCable, then GC does its work as soon as memory limit approaches. The surprise is that (at least in the jvm I'm testing) we have to explicitely reuse stack at the same level. It would be expected that local variables be GCable as soon as the block is exited, but I guess it's a compromise with performance. It would complicate much the bytecode.Like in C, local variables are located in stack beside frames. The stack pointer reserves as much space as required for the local variables in scope. Local variable of an { exited block } become GCable when stack is reused, that is: after a local variable is declared at the same stack level, after the function returns, or after an exit evaluation (catch, loop condition).
They are GCable after :
They are not GCable just after :
NOTE : for a lab, run GC then compare a
WeakReference(my variable)
tonull
.