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