Hi Craig, thank you very much for this complete explanation. That's perfectly understandable and the GC-behaviour which I had expected before. I must have understood something wrong in this thread's discussion, which went on yesterday.
Again, thank you very much for your helpful responses (not only this one). Andreas On 3 Jan 2003 at 11:31, Craig R. McClanahan wrote: > > > On Fri, 3 Jan 2003, Andreas Probst wrote: > > > Hi Craig, > > > > please see intermixed. > > > > On 2 Jan 2003 at 18:18, Craig R. McClanahan wrote: > > > > > > > > Instances can be garbage collected IF AND ONLY IF there are > > > no live references to that object in a static/instance/local > > > variable of some other object that is also in memory. Only > > > instances that are no longer referenced from other object > > > instances can be recycled. > > > > Please consider the following service() or doGet() or so of a > > servlet: > > > > public void service(ServletRequest request, ServletResponse > > response) > > throws IOException > > { > > OtherObject otherObject = new OtherObject(); > > otherObject.doThisAndThat(request, response); > > } > > > > Do I have to place the following > > otherObject = null; > > before the end of service(). Doesn't otherObject be gc-ed > > otherwise? I've never done this. > > The "otherObject" reference goes away as soon as the service() > method returns, so you don't have to actually release it > yourself. HOWEVER, you also need to understand what the > constructor of this class did, and what the doThisAndThat() > method did -- it's still possible for that class to cause memory > leaks which you don't know anything about, or possibly can't do > anything about. > > > > > What about the object instances, which > > otherObject.doThisAndThat() creates? So far I've thought there > > are no live references if otherObject gets gc-ed. > > > > Let's look at a simple case and a complex case: > > SIMPLE CASE: OtherObject has a single instance variable that is > initialized to a String: > > public class OtherObject { > private String id; > public OtherObject(String id) { > this.id = id; > } > public String getId() { > return (this.id); > } > } > > In this case, the only reference to the String pointed at by id > is in this instance of OtherObject. Therefore, when you release > your reference to the OtherObject instance and the id string that > was passed in (because the service() method ended), both the > OtherObject instance and the foo String instance are available > for GC. > > COMPLEX CASE: OtherObject is a little trickier in its > initialization -- it provides a factory pattern method that > creates at most one instance of OtherObject for a particular > identifier string. (This is a *very* common design pattern -- in > fact, Tomcat implements something sort of like this to ensure > that there is at most one instance of each servlet class.) > > public class OtherObject { > > // Private constructor -- use the factory method instead > private OtherObject(String id) { > this.id = id; > } > > // Private instance variable -- one per instance > private String id; > > // Public getter for the "id" property > public String getId() { > return (this.id); > } > > // Static cache of previously created instances > private static HashMap cache = new HashMap(); > > // Factory method for creating OtherObject instances that // > guarantees to create only one for a particular id string > public static OtherObject getOtherObject(String id) { > synchronized (cache) { > OtherObject instance = (OtherObject) cache.get(id); > if (instance == null) { > instance = new OtherObject(id); > cache.put(id, instance); > } > return (instance); > } > } > > } > > To use the factory method, you'd say something like this: > > OtherObject otherObject = > OtherObject.getOtherObject("idstring"); > > instead of: > > OtherObject otherObject = new OtherObject("idstring"); > > and, no matter how many times you call this with the same > parameter value, you'd get the same instance back (basically a > singleton pattern with lazy instantiation). > > Now, your "otherObject" reference still goes away at the end of > the service() method, right? > > Yep. > > So the instance, and it's string, can still be GC'd, right? > > Nope. > > There is still a live reference to each OtherObject instance > sitting in the static HashMap "cache". Therefore, this instance > cannot be GC'd, even though *you* have released your own > reference to it. And, if the OtherObject class is loaded from > Tomcat's common/lib directory (for example), there is no way to > ***ever*** GC this instance, because the public API of the > OtherObject class doesn't offer any way to clear the cache. > > Note also that there is nothing that your servlet can do about > this -- you can't even know if its happening without consulting > the documentation and/or the source code for the classes you are > calling. But the code above will cause a slowly increasing > consumption of memory over time (assuming that you're asking for > different id values), even though *you* are not maintaining any > live references to these objects. > > Craig > > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>