-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Brian,

Brian Munroe wrote:
> Looking at the WEB-INF/lib directory, it has around 76 different jar
> files, some actually used in the application, some (well, most) not.
> They either pertain to legacy features or are functionality duplicate
> (two different versions of Oracle driver libraries, for example)

Yipes!

> I am trying to tune Tomcat because it keeps running out PermGen space,
> so I am using jconsole to inspect the JVM.  I suppose it isn't really
> a profiler, but it is a start.

Just FYI... dropping JAR files isn't likely to reduce your PermGen
usage... classes only get loaded when they're needed. If your
application doesn't use those JARs, they are basically ignored (except
maybe for being scanned for contents for faster class loading). But, you
don't have to worry about all those useless classes actually getting loaded.

You should certainly get rid of useless libraries... just make sure
you're not doing it for the wrong reasons.

> According to jconsole, after doing many application development cycles
> of remove->deployment of *.war to Tomcat (via manager), it looks like
> as many as 20k classes are loaded.  I was under the impression that
> the garbage collector would unload classes as necessary.

This used to happen because Class objects were never discarded by the
JVM. Now, it usually happens when your application somehow stashes an
object somewhere that never goes away. There are several ways to do
that, but off the top of my head I can really only think of one or two:
using static fields to store big object trees and pushing application
data into something managed by Tomcat (JNDI, a Valve, or something like
that).

What ends up happening is that you put some object in one of these
places and, in order to stick around, the parent ClassLoader must remain
in memory (i.e. /not/ GC'd). The ClassLoader keeps all the
java.lang.Class objects it ever loaded, and those will eventually go
into the PermGen space due to their long lives.

I'm a little hazy on PermGen, actually, but I think it /never/ gets
cleaned up. That sounds kinda stupid, but I'm not smart enough to write
my own JVM so what the heck do I know, anyway? If PermGen never gets
cleaned up, maybe your Class objects are just making it into PermGen
naturally, and you are just suffering the consequences of many reloads.

Why are you reloading your webapp so many times? Is this just a
development environment, or do you do this in production?

> I tried to force a GC via jconsole, it reduced the heap memory like it
> should, and it unloaded a few classes pertaining to reflection, but
> nothing like what I was hoping for.  I then leave it be for several
> hours, and all magic like, the GC unloads about 4k classes.

Hmm... that torpedoes my "natural" theory above. Any idea what might
happen in those 4 hours?

> First question.   Anyone tell me why it doesn't unload classes when I
> am trying to force it?  Is classloading/unloading not even the same as
> garbage collection?

First, you can't force the JVM to do anything. Runtime.gc() basically
says to the garbage collector, "now would be a good time to do a
collection", but there's no guarantee. Second, class loading and GC are
mostly unrelated, although as you're seeing, things can get fuzzy when
you're observing problems in either or both areas.

> Second question.  Is having 20k classes loaded normal for a middle
> sized application?

It's not totally crazy, but it is a little high. There are something
like 6k classes that ship with the JVM alone. Of course, you're probably
not using AWT and Swing and stuff like that, but still, there are a lot
of classes out there. Also, Tomcat has a lot of its own classes, and
uses many classes from its dependent libraries, etc.

My relatively small application in development currently has 3386
classes loaded in what looks like 150 ClassLoaders (many of which show
as 'dead' using jmap), and it's been up for several hours at this point
under almost no load.

The same application (well, the last release) in production has 4046
classes loaded, and has been running since 12 July.

> I am assuming if I remove all the unnecessary jars
> from WEB-iNF/lib I can reduce that number?  Would it benefit anything
> to place them in shared/lib?

No! Keep your application and all it's dependencies together. As I
asserted above, reducing the JARs probably won't help.

> Third:  If over 75% of the classes in the jars aren't being called
> anywhere in the application, even though they get loaded on the
> initial application deployment, shouldn't the GC unload them almost
> immediately, since there aren't any open resources using these
> classes.

The classes should never get loaded in the first place.

> Fourth question:  Do my JAVA_OPTS looks decent?

Yes. You might even want to do -verbose:class if you want some light
reading.

Hope that helps,
- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFG4Lvo9CaO5/Lv0PARAkOpAKC6NAM4rH92WDNfpOyKkpnqHLKABQCeOGu0
Gkdkng6CaqDVrnar8LCrWmE=
=7fi9
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to