Reputation: 14449
I have following code:
void method() {
Object o1 = new Object();
{
Object o2 = new Object();
System.out.println(o2);
}
// any long operation
}
will o2 object be eligible for garbage collection during execution of long operation
?
Upvotes: 1
Views: 214
Reputation: 674
No. Even though the object referenced by o2 is not reachable, it will not be garbage-collected. It is in a state between reachable and unreachable called "invisible" because the reference variable o2 is still on the stack.
To make the object garbage-collectible, assign o2 = null
or put that block in another function.
source: A 2001 book on Java performance
Upvotes: 0
Reputation: 719386
The JLS definition of reachability is:
"A reachable object is any object that can be accessed in any potential continuing computation from any live thread."
In this case, the reference ceases to be theoretically accessible to ongoing combutations before the println
call returns. (I'm assuming that println(o2)
doesn't save its the reference somewhere.)
However, in practice no JVMs in existence can tell that the Object becomes unreachable during the call, and most JVMs will only notice this when ... or after ... o2
goes out of scope. And even then, a GC run is not guaranteed to remove the object.
Note: that doesn't contradict the JLS, because the "reachable object" test is really telling you when the object won't be garbage collected, not when it will be. The JLS is careful to specify that an object may be finalized and garbage collected at some point after it becomes unreachable, but that it also may never be finalized and garbage collected.
Upvotes: 2
Reputation: 47749
You need to understand that your variable o2
and the OBJECT DESIGNATED BY o2
are different.
The variable o2 is actually a pointer (though Java prefers to call them "references") and occupies 4 or 8 bytes in the automatic stack frame. This storage is not garbage collected and only goes away when you return from the procedure (or possibly when you exit the {}
brackets depending on compiler implementation).
The object "designated by" (pointed to by) o2 is essentially available for possible garbage collection as soon as the new Object()
operation ends, and the existence of a pointer to it in o2 is all that prevents this. Once the variable o2 either no longer exists in a stack frame or has a different pointer value stored into it then the object is eligible to be collected.
So in your particular case the answer is "maybe". It depends on how the compiler and JIT handle the {}
, along with a few "luck" issues as to whether, having exited the {}
block (but not the method as a whole), the storage location for o2 is reused for something else.
Upvotes: 0
Reputation: 48216
yes however this will depend on whether the JVM/JIT won't optimize this to avoid superfluous stack operations
which would make it
Object o1 = new Object();
Object o2 = new Object();
System.out.println(o2);
// any long operation
many compilers will group all local variable needed and figure out the maximum needed space to keep them all (and some will be eliminated and just kept in registers) and grow the stack accordingly and only shrink it after the function can return
this would mean that o2 will remain in "accessible" memory according to GC unless it was overwritten with another variable in another scope
Upvotes: 0