08-10-2010 06:13 AM
Hello,
I wonder whether the garbage collector handles cyclic references, or whether I should always be using WeakReferences. For example, would the following code create a cyclic reference?
public class MyClass {
private Runnable runnable;
public void init() {
this.runnable = new Runnable() {
public void run() {
MyClass.this.doSomething();
}
}
}
void doSomething() {}
}
If this code is problematic, how can I fix it?
Thank you.
08-10-2010 08:04 AM
> ... whether the garbage collector handles cyclic references ...
Modern garbage collectors handle cyclic references just fine. And I believe that RIM implementation is pretty good - their Java VM needs to work for days in embeded environment with limited resources.
> would the following code create a cyclic reference?
No.
Once doSomething() is done, runnable object won't have any references to the outer class.
If doSomething() does not exit - well it is not GC question any more ![]()
08-11-2010 05:32 AM
@Plato: Do you have any references that document this property? I am not sure, and the `WeakReference` class is still there and not deprecated, which could indicate otherwise.
As for my code, it does maintain a cyclic reference. The runnable object has a reference to the object of the outer class, and the outer class is maintaing a reference to it in the "runnable" variable. This creates a cyclic reference. Think of this runnable as a MenuItem instead, and my point should be clarified.
08-11-2010 08:20 AM
Weak References are very useful, for example for references to things that 'belong' to other people, by using a Weak Reference you don't stop the other person freeing the Object. The fact that they are present is not related to your question about circular references.
I have never seen detailed documentation on the garbage collector, however I would, as Plato suggested, assume that something as obvious as a cyclic reference is catered for by it.
In your case, the Runnable object runnable, is not going to be a candidate for garbage collection until the instance of MyClass is de-referenced, so the fact that there is possible circular reference is irrelevant.
Running <myclass>.init() would result in a new Runnable being created, which because of the cyclic reference, might appear to cause a memory leak. I'm pretty sure that is not the case however, because the runnable in MyClass, only points to the most current Runnable, so the previous one would be a candidate for garbage collection.