I have been, without a question, using the final
keyword for years to denote fields that should not change for the lifetime of an instance/class. Suddenly this occured to me...
So given this example:
public class TestFinalGC{
private TestFinalGC(){}
private final Object obj = new Object();
public static void main(String []args){
TestFinalGC instance = new TestFinalGC();
// instance Ref -> actual instance ->? obj ref-> actual obj
System.out.println(instance.obj);
instance = null;
//say GC makes sweep here... what happens?
//lets assume theres more code, obj would obviously be eligible for GC on app exit.
}
}
How does the obj
member NOT leak here? Are final
fields automatically WeakReferences such that if the strong references to parent(s) are nulled, they are eligible for garbage collection?
The JLS does not seem to note anything special about final
Update:
So this question of mine was founded on the premise that "reachability" and strong/weak references are closely related. There is this confusing oracle doc on reachability that leads me to believe that nested references should always be "strongly reachable". Hence, I do null my nested object references in all my objects, but it appears that this obviously should not be the case from all of the comments I am receiving.
So regarding "reachability", then, is it simply just that nested object references are no longer considered "reachable" if parent references are no longer reachable?
It could be is true that the premise of this problem is incorrect, but there is still intriguing information to consolidate here.
Final variables cannot be changed after initial assignment (enforced by the compiler). This does not change the behaviour of the garbage collection as such. Only thing is that these variables cannot be nulled when not being used any more (which may help the garbage collection in memory tight situations).
Use reference objects to avoid memory leaks Using the java. lang. ref package, you can work with the garbage collector in your program. This allows you to avoid directly referencing objects and use special reference objects that the garbage collector easily clears.
In general, a Java memory leak happens when an application unintentionally (due to logical errors in code) holds on to object references that are no longer required. These unintentional object references prevent the built-in Java garbage collection mechanism from freeing up the memory consumed by these objects.
DEFINITION A memory leak is the gradual deterioration of system performance that occurs over time as the result of the fragmentation of a computer's RAM due to poorly designed or programmed applications that fail to free up memory segments when they are no longer needed.
As Makoto suggested, there is simply nothing special about final
in variable declarations as far as GC is concerned. In your example code
private final Object obj = new Object();
will be garbage collected at the same time as
private Object obj = new Object();
Both are strong references, but are invalidated and garbage collected together with their parent class TestFinalGC
instance. That is because when the instance is GC'd, the reference fields are destroyed as well and the references do not exist any more. obj's reference count thus decreases by one.
However, should you write something like
Object x = myTestFinalGC.obj; // only works if your obj is not private, of course
Then the object will not be garbage collected because it will still have one reference lingering around (assuming this particular line of code is in another class instance that remains alive when myTestFinalGC is garbage collected.
tl;dr: memory allocations are garbage collected when their hard reference count drops to zero (and the collector runs, of course). final
doesn't change this fact.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With