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]>

Reply via email to