You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Brandon Cruz <bc...@norvax.com> on 2003/01/02 23:16:23 UTC

Memory Usage and Garbage Collection

Do loaded jsp pages and/or class files ever get garbage collected when
tomcat is running?

We have a production server with several hundred virtual hosts per host,
each with a fair share of jsp pages and with moderate to low traffic per
host.  As time goes on, the amount of memory being used constantly grows.
It starts off around 60MB, then goes higher and higher, getting up to around
100MB after a couple days.

The regular GC seems to usually clean up around 2MB ([GC
99493K->97502K(204544K), 0.0243521 secs]) and the Full GC seems to clean up
less than that ([Full GC 97388K->97187K(204544K), 2.4269915 secs]).

Since I have the -Xmx and -Xms set to 200MB, the 204544K number never gets
resized, but the number before the -> seems to slowly and steadily rise.

Full GC seems to run quite often, every few seconds, GC runs once in a
while, but spits out about 50 lines at once every time it runs.  Is this
normal?  Shouldn't Full GC only run once in a while?

I am starting to think that as classes and jsp's are loaded, they stay in
memory and are never released until tomcat is restarted, which means that
there is eventually a point where all the classes will load and I just need
to have enough memory to support that without having to use swap space.

The problem occurs when the memory usage number before the -> gets up to
about 130.  The system is using swap space and eventually out of memory
errors start showing up.

Any ideas?  More Ram, more tuning, different site architecture?

Thanks in advance?

Brandon



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Memory Usage and Garbage Collection

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Fri, 3 Jan 2003, Julian Löffelhardt wrote:

> Date: Fri, 3 Jan 2003 02:01:58 +0100
> From: Julian Löffelhardt <ju...@austria.fm>
> Reply-To: Tomcat Users List <to...@jakarta.apache.org>
> To: Tomcat Users List <to...@jakarta.apache.org>
> Subject: Re: Memory Usage and Garbage Collection
>
> Looking at the jasper source of tomcat 4.0.4 releasing jsp's seems to be
> reasonable easy to implement:
> The Jsp's classloader, the class and the actual jsp-servlet instance  are
> all put together in a JspServletWrapper-Object which itself is stored in the
> JspServlet (the Servlet used to executing jsps) using a Hashtable.
> One could replace the hashtable with a LRU-Cache or anything.
>
> Since each jsp is loaded using a separate classloader, removing the Wrapper
> removes the reference to the instance, it's class and it's loader, which
> should enable the class garbage collector to remove the class.
>
> Do you think this approach is reasonable?
> Does this part of the implementation differ with Jasper2?
>

You'd best examine the sources to figure that out :-).  But Jasper2 is
radically different than Jasper1.

But remember, it's not just a matter of throwing away the reference to the
compiled servlet class.  You also need to ensure that the destroy() method
gets called as the servlet API requires -- all the while ensuring that no
additional requests start getting processed through the service method.

And, don't forget that this will harm performance for the vast majority of
users who *do* have adequate memory on their servers, so nothing like this
should be enabled by default.

> This is a feature I could really use well.
>
> llap,
> julian

Craig

>
> ----- Original Message -----
> From: "Craig R. McClanahan" <cr...@apache.org>
> To: "Tomcat Users List" <to...@jakarta.apache.org>; <bc...@norvax.com>
> Sent: Friday, January 03, 2003 1:12 AM
> Subject: Re: Memory Usage and Garbage Collection
>
>
> >
> >
> > On Thu, 2 Jan 2003, Brandon Cruz wrote:
> >
> > > Date: Thu, 2 Jan 2003 16:16:23 -0600
> > > From: Brandon Cruz <bc...@norvax.com>
> > > Reply-To: Tomcat Users List <to...@jakarta.apache.org>,
> > >      bcruz@norvax.com
> > > To: Tomcat Users List <to...@jakarta.apache.org>
> > > Subject: Memory Usage and Garbage Collection
> > >
> > > Do loaded jsp pages and/or class files ever get garbage collected when
> > > tomcat is running?
> > >
> >
> > It's legal for servlet containers to destroy and release servlets and JSP
> > pages while the server is running, but Tomcat doesn't currently do so.
> > Once a servlet or JSP is loaded, it stays loaded until you reload that
> > particular webapp or you shut Tomcat down.
> >
> > > We have a production server with several hundred virtual hosts per host,
> > > each with a fair share of jsp pages and with moderate to low traffic per
> > > host.  As time goes on, the amount of memory being used constantly
> grows.
> > > It starts off around 60MB, then goes higher and higher, getting up to
> around
> > > 100MB after a couple days.
> > >
> > > The regular GC seems to usually clean up around 2MB ([GC
> > > 99493K->97502K(204544K), 0.0243521 secs]) and the Full GC seems to clean
> up
> > > less than that ([Full GC 97388K->97187K(204544K), 2.4269915 secs]).
> > >
> > > Since I have the -Xmx and -Xms set to 200MB, the 204544K number never
> gets
> > > resized, but the number before the -> seems to slowly and steadily rise.
> > >
> > > Full GC seems to run quite often, every few seconds, GC runs once in a
> > > while, but spits out about 50 lines at once every time it runs.  Is this
> > > normal?  Shouldn't Full GC only run once in a while?
> > >
> > > I am starting to think that as classes and jsp's are loaded, they stay
> in
> > > memory and are never released until tomcat is restarted, which means
> that
> > > there is eventually a point where all the classes will load and I just
> need
> > > to have enough memory to support that without having to use swap space.
> > >
> >
> > It's not just the classes -- it's the object instances created from those
> > classes that take up space (the bytecodes of the class itself exist only
> > once).
> >
> > > The problem occurs when the memory usage number before the -> gets up to
> > > about 130.  The system is using swap space and eventually out of memory
> > > errors start showing up.
> > >
> > > Any ideas?  More Ram, more tuning, different site architecture?
> > >
> >
> > If you're using swap space, you probably have your max heap size (-Xmx)
> > too large for the amount of physical memory that is available.  I'd
> > definitely start by either reducing -Xmx or increasing the amount of
> > physical RAM.  If reducing -Xmx gives you OutOfMemoryException errors,
> > then increasing RAM is the only option.
> >
> > The second thing I'd do is review my applications for places where they
> > might be maintaining references to data in between requests, either in
> > instance variables of the servlet or JSP class or by keeping too many
> > things in the user's session for too long.  If there are such references,
> > your user data objects cannot be GC'd and you'll end up with exactly the
> > pattern you describe (slowly increasing memory use).
> >
> > > Thanks in advance?
> > >
> > > Brandon
> >
> > Craig
> >
> >
> > --
> > To unsubscribe, e-mail:
> <ma...@jakarta.apache.org>
> > For additional commands, e-mail:
> <ma...@jakarta.apache.org>
> >
> >
>
>
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Memory Usage and Garbage Collection

Posted by Julian Löffelhardt <ju...@austria.fm>.
Looking at the jasper source of tomcat 4.0.4 releasing jsp's seems to be
reasonable easy to implement:
The Jsp's classloader, the class and the actual jsp-servlet instance  are
all put together in a JspServletWrapper-Object which itself is stored in the
JspServlet (the Servlet used to executing jsps) using a Hashtable.
One could replace the hashtable with a LRU-Cache or anything.

Since each jsp is loaded using a separate classloader, removing the Wrapper
removes the reference to the instance, it's class and it's loader, which
should enable the class garbage collector to remove the class.

Do you think this approach is reasonable?
Does this part of the implementation differ with Jasper2?

This is a feature I could really use well.

llap,
julian

----- Original Message -----
From: "Craig R. McClanahan" <cr...@apache.org>
To: "Tomcat Users List" <to...@jakarta.apache.org>; <bc...@norvax.com>
Sent: Friday, January 03, 2003 1:12 AM
Subject: Re: Memory Usage and Garbage Collection


>
>
> On Thu, 2 Jan 2003, Brandon Cruz wrote:
>
> > Date: Thu, 2 Jan 2003 16:16:23 -0600
> > From: Brandon Cruz <bc...@norvax.com>
> > Reply-To: Tomcat Users List <to...@jakarta.apache.org>,
> >      bcruz@norvax.com
> > To: Tomcat Users List <to...@jakarta.apache.org>
> > Subject: Memory Usage and Garbage Collection
> >
> > Do loaded jsp pages and/or class files ever get garbage collected when
> > tomcat is running?
> >
>
> It's legal for servlet containers to destroy and release servlets and JSP
> pages while the server is running, but Tomcat doesn't currently do so.
> Once a servlet or JSP is loaded, it stays loaded until you reload that
> particular webapp or you shut Tomcat down.
>
> > We have a production server with several hundred virtual hosts per host,
> > each with a fair share of jsp pages and with moderate to low traffic per
> > host.  As time goes on, the amount of memory being used constantly
grows.
> > It starts off around 60MB, then goes higher and higher, getting up to
around
> > 100MB after a couple days.
> >
> > The regular GC seems to usually clean up around 2MB ([GC
> > 99493K->97502K(204544K), 0.0243521 secs]) and the Full GC seems to clean
up
> > less than that ([Full GC 97388K->97187K(204544K), 2.4269915 secs]).
> >
> > Since I have the -Xmx and -Xms set to 200MB, the 204544K number never
gets
> > resized, but the number before the -> seems to slowly and steadily rise.
> >
> > Full GC seems to run quite often, every few seconds, GC runs once in a
> > while, but spits out about 50 lines at once every time it runs.  Is this
> > normal?  Shouldn't Full GC only run once in a while?
> >
> > I am starting to think that as classes and jsp's are loaded, they stay
in
> > memory and are never released until tomcat is restarted, which means
that
> > there is eventually a point where all the classes will load and I just
need
> > to have enough memory to support that without having to use swap space.
> >
>
> It's not just the classes -- it's the object instances created from those
> classes that take up space (the bytecodes of the class itself exist only
> once).
>
> > The problem occurs when the memory usage number before the -> gets up to
> > about 130.  The system is using swap space and eventually out of memory
> > errors start showing up.
> >
> > Any ideas?  More Ram, more tuning, different site architecture?
> >
>
> If you're using swap space, you probably have your max heap size (-Xmx)
> too large for the amount of physical memory that is available.  I'd
> definitely start by either reducing -Xmx or increasing the amount of
> physical RAM.  If reducing -Xmx gives you OutOfMemoryException errors,
> then increasing RAM is the only option.
>
> The second thing I'd do is review my applications for places where they
> might be maintaining references to data in between requests, either in
> instance variables of the servlet or JSP class or by keeping too many
> things in the user's session for too long.  If there are such references,
> your user data objects cannot be GC'd and you'll end up with exactly the
> pattern you describe (slowly increasing memory use).
>
> > Thanks in advance?
> >
> > Brandon
>
> Craig
>
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: Memory Usage and Garbage Collection

Posted by Andreas Probst <an...@gmx.net>.
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:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Memory Usage and Garbage Collection

Posted by Nikola Milutinovic <Ni...@ev.co.yu>.
> 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.

Wouldn't it be the responsibility of the Factory to worry about releasing 
objects to the GC?

I mean, if it implements caching, it should have some sort of policy when an 
instantiated (and, thus, cached) object is a candidate for GC. Obvious 
guidelines are:

- if it is not used
- if it has last been used less recently than some limit

One can also think of a non-linear function, which checks the available memory 
or has it's internal memory limit.

Nix.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: Memory Usage and Garbage Collection

Posted by "Noel J. Bergman" <no...@devtech.com>.
> There is still a live reference to each OtherObject instance sitting in
> the static HashMap "cache".

> there is no way to ***ever*** GC this instance

Another example of a similar memory leak is the File.deleteOnExit method.
It should not be used without extreme care and understanding in a server
application, since the system has to hold onto memory related to deleting
the file until the JVM shuts down.

	--- Noel


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: Memory Usage and Garbage Collection

Posted by "Craig R. McClanahan" <cr...@apache.org>.

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:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: Memory Usage and Garbage Collection

Posted by Andreas Probst <an...@gmx.net>.
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.

What about the object instances, which 
otherObject.doThisAndThat() creates? So far I've thought there 
are no live references if otherObject gets gc-ed.

> 
> In the case at hand, Tomcat (obviously) has references to all the
> servlets that it has loaded.  Therefore, those servlet instances
> cannot be garbage collected.  Furthermore, any object that is
> referenced by static or instance variables of your servlet class
> can *also* not be garbage collected, because live references
> still exist.  Same thing for session attributes.

OK, this is obvious.

Andreas

deleted the latter parts...




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: Memory Usage and Garbage Collection

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Thu, 2 Jan 2003, Brandon Cruz wrote:

> Date: Thu, 2 Jan 2003 19:04:55 -0600
> From: Brandon Cruz <bc...@norvax.com>
> To: Tomcat Users List <to...@jakarta.apache.org>
> Cc: craigmcc@apache.org
> Subject: RE: Memory Usage and Garbage Collection
>
> Craig,
>
> Thanks for your comments, I still have a few clarification questions.
>
> 1)It's not just the classes -- it's the object instances created from those
> classes that take up space (the bytecodes of the class itself exist only
> once).  ---does this mean that every object instance is never garbage
> collected, or are these instances collected?
>

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.

In the case at hand, Tomcat (obviously) has references to all the servlets
that it has loaded.  Therefore, those servlet instances cannot be garbage
collected.  Furthermore, any object that is referenced by static or
instance variables of your servlet class can *also* not be garbage
collected, because live references still exist.  Same thing for session
attributes.

In the very early days of Java, classes themselves could be GC'd if there
were no live instances of that class.  However, this caused more grief
than it was worth, so that went away (about JDK 1.1 or so).  In today's
world, the only way to throw away a class instance is to throw away the
class loader that loaded it (which is how Tomcat implements webapp
reloading).

> 2)What about instances of the classes, does every instance stay in memory
> forever?  Are they loaded into the sessions, or are they pooled somehow?
> What about the instance variables of these classes, I assume they get
> collected after the class instances would be collected.

As above, instances ALWAYS stay in memory as long as there are live
references.  If there are no live references, the GC is free to clean them
up if and when it feels like it.

>
> If class instances stay in memory forever, I would think there is no
> possible way to ever keep the system running without a restart.
>

As above, you can throw away references to a ClassLoader, and that will
ultimately cause all the instances to be collected -- but ONLY if there
are not any references to any instances of classes loaded by that
ClassLoader somewhere else.

Phew, that doesn't make sense -- can we describe a sample use case?

Sure.  Consider the fact that Tomcat provides more than one class loader
(see
http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html).
The common and shared class loaders are never thrown away, so any classes
loaded from there will stay in memory for the lifetime of Tomcat.  But
wait, there's more.

Assume that you've got a class, loaded from a library in common/lib, that
maintains a collection as a static variable.  Now, assume you've called a
method on this class, and passed it a reference to a bean (or something)
that is loaded from your webapp (i.e. it's in WEB-INF/classes or
WEB-INF/lib), and this reference gets added to the static collection.
Now, ask Tomcat to reload this application.  What happens?

Tomcat dutifully throws away its reference to the webapp class loader.
Normally, that means everything loaded from that class loader is now
garbage and can be collected.  HOWEVER, because there is still a live
reference to one of the objects from your old webapp in the static
collection.  Therefore, GC cannot process:
* The instance of your bean class that was referenced
* The class of your bean
* The webapp class loader
* Any other objects referenced by the webapp class loader.

In short, the above scenario just created a memory leak.

The best thing you can do to avoid problems like this is to make your
webapps self contained, and to always release references to objects you
don't need any longer.

> Brandon

Craig


>
> -----Original Message-----
> From: Craig R. McClanahan [mailto:craigmcc@apache.org]
> Sent: Thursday, January 02, 2003 6:12 PM
> To: Tomcat Users List; bcruz@norvax.com
> Subject: Re: Memory Usage and Garbage Collection
>
>
>
>
> On Thu, 2 Jan 2003, Brandon Cruz wrote:
>
> > Date: Thu, 2 Jan 2003 16:16:23 -0600
> > From: Brandon Cruz <bc...@norvax.com>
> > Reply-To: Tomcat Users List <to...@jakarta.apache.org>,
> >      bcruz@norvax.com
> > To: Tomcat Users List <to...@jakarta.apache.org>
> > Subject: Memory Usage and Garbage Collection
> >
> > Do loaded jsp pages and/or class files ever get garbage collected when
> > tomcat is running?
> >
>
> It's legal for servlet containers to destroy and release servlets and JSP
> pages while the server is running, but Tomcat doesn't currently do so.
> Once a servlet or JSP is loaded, it stays loaded until you reload that
> particular webapp or you shut Tomcat down.
>
> > We have a production server with several hundred virtual hosts per host,
> > each with a fair share of jsp pages and with moderate to low traffic per
> > host.  As time goes on, the amount of memory being used constantly grows.
> > It starts off around 60MB, then goes higher and higher, getting up to
> around
> > 100MB after a couple days.
> >
> > The regular GC seems to usually clean up around 2MB ([GC
> > 99493K->97502K(204544K), 0.0243521 secs]) and the Full GC seems to clean
> up
> > less than that ([Full GC 97388K->97187K(204544K), 2.4269915 secs]).
> >
> > Since I have the -Xmx and -Xms set to 200MB, the 204544K number never gets
> > resized, but the number before the -> seems to slowly and steadily rise.
> >
> > Full GC seems to run quite often, every few seconds, GC runs once in a
> > while, but spits out about 50 lines at once every time it runs.  Is this
> > normal?  Shouldn't Full GC only run once in a while?
> >
> > I am starting to think that as classes and jsp's are loaded, they stay in
> > memory and are never released until tomcat is restarted, which means that
> > there is eventually a point where all the classes will load and I just
> need
> > to have enough memory to support that without having to use swap space.
> >
>
> It's not just the classes -- it's the object instances created from those
> classes that take up space (the bytecodes of the class itself exist only
> once).
>
> > The problem occurs when the memory usage number before the -> gets up to
> > about 130.  The system is using swap space and eventually out of memory
> > errors start showing up.
> >
> > Any ideas?  More Ram, more tuning, different site architecture?
> >
>
> If you're using swap space, you probably have your max heap size (-Xmx)
> too large for the amount of physical memory that is available.  I'd
> definitely start by either reducing -Xmx or increasing the amount of
> physical RAM.  If reducing -Xmx gives you OutOfMemoryException errors,
> then increasing RAM is the only option.
>
> The second thing I'd do is review my applications for places where they
> might be maintaining references to data in between requests, either in
> instance variables of the servlet or JSP class or by keeping too many
> things in the user's session for too long.  If there are such references,
> your user data objects cannot be GC'd and you'll end up with exactly the
> pattern you describe (slowly increasing memory use).
>
> > Thanks in advance?
> >
> > Brandon
>
> Craig
>
>
> --
> To unsubscribe, e-mail:
> <ma...@jakarta.apache.org>
> For additional commands, e-mail:
> <ma...@jakarta.apache.org>
>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: Memory Usage and Garbage Collection

Posted by Brandon Cruz <bc...@norvax.com>.
Craig,

Thanks for your comments, I still have a few clarification questions.

1)It's not just the classes -- it's the object instances created from those
classes that take up space (the bytecodes of the class itself exist only
once).  ---does this mean that every object instance is never garbage
collected, or are these instances collected?

2)What about instances of the classes, does every instance stay in memory
forever?  Are they loaded into the sessions, or are they pooled somehow?
What about the instance variables of these classes, I assume they get
collected after the class instances would be collected.

If class instances stay in memory forever, I would think there is no
possible way to ever keep the system running without a restart.

Brandon

-----Original Message-----
From: Craig R. McClanahan [mailto:craigmcc@apache.org]
Sent: Thursday, January 02, 2003 6:12 PM
To: Tomcat Users List; bcruz@norvax.com
Subject: Re: Memory Usage and Garbage Collection




On Thu, 2 Jan 2003, Brandon Cruz wrote:

> Date: Thu, 2 Jan 2003 16:16:23 -0600
> From: Brandon Cruz <bc...@norvax.com>
> Reply-To: Tomcat Users List <to...@jakarta.apache.org>,
>      bcruz@norvax.com
> To: Tomcat Users List <to...@jakarta.apache.org>
> Subject: Memory Usage and Garbage Collection
>
> Do loaded jsp pages and/or class files ever get garbage collected when
> tomcat is running?
>

It's legal for servlet containers to destroy and release servlets and JSP
pages while the server is running, but Tomcat doesn't currently do so.
Once a servlet or JSP is loaded, it stays loaded until you reload that
particular webapp or you shut Tomcat down.

> We have a production server with several hundred virtual hosts per host,
> each with a fair share of jsp pages and with moderate to low traffic per
> host.  As time goes on, the amount of memory being used constantly grows.
> It starts off around 60MB, then goes higher and higher, getting up to
around
> 100MB after a couple days.
>
> The regular GC seems to usually clean up around 2MB ([GC
> 99493K->97502K(204544K), 0.0243521 secs]) and the Full GC seems to clean
up
> less than that ([Full GC 97388K->97187K(204544K), 2.4269915 secs]).
>
> Since I have the -Xmx and -Xms set to 200MB, the 204544K number never gets
> resized, but the number before the -> seems to slowly and steadily rise.
>
> Full GC seems to run quite often, every few seconds, GC runs once in a
> while, but spits out about 50 lines at once every time it runs.  Is this
> normal?  Shouldn't Full GC only run once in a while?
>
> I am starting to think that as classes and jsp's are loaded, they stay in
> memory and are never released until tomcat is restarted, which means that
> there is eventually a point where all the classes will load and I just
need
> to have enough memory to support that without having to use swap space.
>

It's not just the classes -- it's the object instances created from those
classes that take up space (the bytecodes of the class itself exist only
once).

> The problem occurs when the memory usage number before the -> gets up to
> about 130.  The system is using swap space and eventually out of memory
> errors start showing up.
>
> Any ideas?  More Ram, more tuning, different site architecture?
>

If you're using swap space, you probably have your max heap size (-Xmx)
too large for the amount of physical memory that is available.  I'd
definitely start by either reducing -Xmx or increasing the amount of
physical RAM.  If reducing -Xmx gives you OutOfMemoryException errors,
then increasing RAM is the only option.

The second thing I'd do is review my applications for places where they
might be maintaining references to data in between requests, either in
instance variables of the servlet or JSP class or by keeping too many
things in the user's session for too long.  If there are such references,
your user data objects cannot be GC'd and you'll end up with exactly the
pattern you describe (slowly increasing memory use).

> Thanks in advance?
>
> Brandon

Craig


--
To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
For additional commands, e-mail:
<ma...@jakarta.apache.org>



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Memory Usage and Garbage Collection

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Thu, 2 Jan 2003, Brandon Cruz wrote:

> Date: Thu, 2 Jan 2003 16:16:23 -0600
> From: Brandon Cruz <bc...@norvax.com>
> Reply-To: Tomcat Users List <to...@jakarta.apache.org>,
>      bcruz@norvax.com
> To: Tomcat Users List <to...@jakarta.apache.org>
> Subject: Memory Usage and Garbage Collection
>
> Do loaded jsp pages and/or class files ever get garbage collected when
> tomcat is running?
>

It's legal for servlet containers to destroy and release servlets and JSP
pages while the server is running, but Tomcat doesn't currently do so.
Once a servlet or JSP is loaded, it stays loaded until you reload that
particular webapp or you shut Tomcat down.

> We have a production server with several hundred virtual hosts per host,
> each with a fair share of jsp pages and with moderate to low traffic per
> host.  As time goes on, the amount of memory being used constantly grows.
> It starts off around 60MB, then goes higher and higher, getting up to around
> 100MB after a couple days.
>
> The regular GC seems to usually clean up around 2MB ([GC
> 99493K->97502K(204544K), 0.0243521 secs]) and the Full GC seems to clean up
> less than that ([Full GC 97388K->97187K(204544K), 2.4269915 secs]).
>
> Since I have the -Xmx and -Xms set to 200MB, the 204544K number never gets
> resized, but the number before the -> seems to slowly and steadily rise.
>
> Full GC seems to run quite often, every few seconds, GC runs once in a
> while, but spits out about 50 lines at once every time it runs.  Is this
> normal?  Shouldn't Full GC only run once in a while?
>
> I am starting to think that as classes and jsp's are loaded, they stay in
> memory and are never released until tomcat is restarted, which means that
> there is eventually a point where all the classes will load and I just need
> to have enough memory to support that without having to use swap space.
>

It's not just the classes -- it's the object instances created from those
classes that take up space (the bytecodes of the class itself exist only
once).

> The problem occurs when the memory usage number before the -> gets up to
> about 130.  The system is using swap space and eventually out of memory
> errors start showing up.
>
> Any ideas?  More Ram, more tuning, different site architecture?
>

If you're using swap space, you probably have your max heap size (-Xmx)
too large for the amount of physical memory that is available.  I'd
definitely start by either reducing -Xmx or increasing the amount of
physical RAM.  If reducing -Xmx gives you OutOfMemoryException errors,
then increasing RAM is the only option.

The second thing I'd do is review my applications for places where they
might be maintaining references to data in between requests, either in
instance variables of the servlet or JSP class or by keeping too many
things in the user's session for too long.  If there are such references,
your user data objects cannot be GC'd and you'll end up with exactly the
pattern you describe (slowly increasing memory use).

> Thanks in advance?
>
> Brandon

Craig


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>