tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <craig...@apache.org>
Subject RE: Memory Usage and Garbage Collection
Date Fri, 03 Jan 2003 02:18:51 GMT


On Thu, 2 Jan 2003, Brandon Cruz wrote:

> Date: Thu, 2 Jan 2003 19:04:55 -0600
> From: Brandon Cruz <bcruz@norvax.com>
> To: Tomcat Users List <tomcat-user@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 <bcruz@norvax.com>
> > Reply-To: Tomcat Users List <tomcat-user@jakarta.apache.org>,
> >      bcruz@norvax.com
> > To: Tomcat Users List <tomcat-user@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:
> <mailto:tomcat-user-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail:
> <mailto:tomcat-user-help@jakarta.apache.org>
>
>
>


--
To unsubscribe, e-mail:   <mailto:tomcat-user-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:tomcat-user-help@jakarta.apache.org>


Mime
View raw message