I will preface this question with the statement that I am new to Java garbage collection, so if the collector takes care of the problem I will be happy with that. Or if I am woefully ignorant Java memory allocation, which I in fact am, I apologize. But, I am considering the following three scenarios:
public class ScenarioA implements MyQuestion{
private Field field;
public Field getField(){
if(field == null){
field = new Field(this);
}
return field;
}
vs.
public class ScenarioB implements MyQuestion{
public Field getField(){
return new Field(this);
}
}
vs.
import java.lang.ref.WeakReference;
public class ScenearioC implements MyQuestion{
private WeakReference<Field> weakField;
public Field getField(){
if(WeakField == null || weakField.get() == null){
weakField = new WeakReference(new Field(this));
}
return weakField.get();
}
}
I think that ScenarioA is just bad, because if .get() is ever called on an instance of ScenarioA, we will maintain strong references between that instance of ScenarioA and the instance of Field returned by the .get() method, meaning that neither will ever be garbage-collected, whether or not the program actually cares about either one.
ScenarioB has the problem of potentially instantiating a vary large number of .equal objects, which could be very expensive and unnecessary.
ScebarioC I understand the least. I have tried to read the source for WeakReference (here), but I can't figure out what's going on. I'd like to blame that on certain GC/VM opperations happening behind the scenes, but I'd like to blame a lot of things on a lot of other things. Anyway, it seems to me that every WeakReference must require strictly more memory than simply maintaining a reference to the referent, since we must first maintain a reference to the WeakReference, which then maintains a reference to the actual object. (My apologies for that sentence). This could be bad if Field is large and/or we instantiate several ScenarioA's. More importantly though, it appears to me that each WeakReference requires its own thread, which itself (the thread) appears to never die unless the instance ScenarioC--and thus the weak reference-- dies. This could be really bad if there are a lot of instances of ScenarioC.
Does anyone have a solution to this problem?