Several replies...

> From: "Mike Bachrynowski" <[EMAIL PROTECTED]>
> Sent: Thursday, January 23, 2003 7:02 AM
> Subject: RE: Memory Mgmt Tomcat


> We run high volume, load balanced and multiple web, servlet, application
> and database servers on physically different machines. One of the
> problem areas is persistence of sessions.  Even if the application knows
> that a session is never going to be used again it hangs around and uses
> memory until such time as Java garbage collection cuts in.

To me, this is one of the most major issues of Java Servlet engines in
general. When you have a Session with a long lifetime (15-30 minutes), you
are pretty much guaranteed that the Session object and its dependents are
going to thrown into the Old space on any reasonably active server.

This can be considered a Bad Thing as generational collectors tend to make
it "cheap" to GC the younger generations of objects, where a vast majority
of objects are created and thrown away. The older the objects get, the more
entrenched they become and, potentially, the harder (more expensive) they
are to GC.

The logic behind this is that many systems will have several essentially
static objects that are simply never going to go away during the life of the
program (say, for example, the java.lang.String class). As a generational
collector works through its heap of objects, it finds objects in the first
generation that never seem to Go Away and get freed. Eventually, the
collector will basicly tire of constant;y seeing this object and move into a
older generation, which gets swept less often than the younger generations.

A simplistic view is that you have, say, 3 pools of memory. As the first
pool fills up you go through it and discard the freed objects. After several
interations, you find that there are a bunch of objects that are always
there. Rather than constantly scanning those objects, you throw them into
another pool. When THAT pool fills up, you do the same thing, and so on.

The idea is to make the routine sweep of real garbage, (i.e. simple work
objects) as quick as possible.

Now, the problem with Sessions is that they have an extended lifetime. By
their very nature, Sessions are pretty much implicitly garbage, as they only
represent the lifespan of the users actual interaction with the application.
That means that sooner or later, the user will Go Away, and the Session will
have served its pupose and can be collected.

The problem of course is that there really isn't a way to enforce having a
user "log off" of an application. Most simply drift away never to return,
putting the application on hold until the Session times out, typically in
15-30 minutes for many apps. During that idle time, these Sessions are
buried into these older generation for objects. 30 minutes is a long time to
the Garbage Collector. After 30 minutes, it is easy to see how the JVM can
make the assumption that SessionID 12345 is as important to the application
as java.lang.String, and promote it to the same level in the heap.

So, while the young generation is designed to be quickly and rapidly flushed
through, the old generation can be more time consuming to process, mostly
because of its size and the number of objects.

If you have objects that are "too old" for the younger generation, but not
really "old enough" for the older generation, you end up with sort of a GC
thrashing scenario where you are filling the older generation faster than
necessary and causing more expensive GCs to happen.

Some of this can be tuned away with the GC parameters on the JVMs but that's
as much art as it is science.

The other problem regarding Sessions is also the simple fact that even with
a well tuned GC, they're still going to live with your application for at
least the amount of time that the Session times out.

What this means is that should your site get a sudden surge in traffic, your
site will have to "live" with that traffic potentially long after the
traffic has left. Like that big cloud of black smoke that a bus leaves as is
accelerates away from the bus stop. The bus is gone, but the stink lingers.

Mike has done some good work in identfying those requests which simply don't
need the Sessions. In our application, were pretty much doomed once the user
logs in (which they have to do to do anything). So, even the most casual
quick glance in our system can cause horrible repercussions within the
memory, unless they thoughfully hit the Log Out Button, but even that gets
real ugly because of how web apps work.

Long term, though, it's simply a matter that you should strive to keep your
sessions small. I don't know if Tomcat can persist the Sessions to disk and
deactive them before they time out (like after 5 minutes) in order to free
up some long term memory. No doubt, this can be done directly in code,
but...it's a tricky thing.

I know, this is a meaningless post with no real concrete help, but just some
observations.

Anyway, to move on...

> From: Hari Venkatesan [mailto:[EMAIL PROTECTED]]
> Sent: 23 January 2003 14:30
> Subject: RE: Memory Mgmt Tomcat

> Off late there have been many  queries about memory management and the
> reason behind this is because people get bombarded with "out of memory
> error".

Despite what was mentioned previosly, there are assorted reasons why folks
are getting the Out Of Memory exception.

A very common one is simply that the stock Sun JVM javac leaks memory, so if
you're compiling a bunch of JSPs, you WILL run out of memory and there isn't
much you can do about it (though there might be a way to fork the javac, I
haven't looked in to that).

Another issue that came up recently was that essentially once a Servlet is
loaded into Tomcat, Tomcat never Let's Go. This is normally not a problem.
Most Servlets are actually pretty small. However, since JSPs create
Servlets, if you have a lot of JSPs in your system, and they tend to have a
lot of content, then you will end up filling your heap with RAM copies of
your JSPs.

If you use JSPs like others use HTML or SHTML files, this too will cause you
to run out of memory.

But, simply put, Out Of Memory is not a GC problem, it's a resource problem
due to the application directly or side effects of the Tomcat implementation
(as mentioned above).

GC problems are when your JVM goes out to lunch for 2 minutes doing a Full
GC on a heap that's been half swapped to disk. Tuning of the GC is designed
to mitigate the surprises and impact of the collector upon your programs
execution.

Of course, the REAL problem with all of this is that the answer to anyones
question regarding this topic is "It Depends", because everyones situation
is different and a whole host of environmental aspects, system design,
coding practices, etc impact memory and there's no One Answer. Now, most of
those issues are almost impossible to cogently communicate over something as
low bandwidth as a mailing list.

It's funny how hard it is to communicate the important facts and details of
a problem, but how easy it is to communicate frustration and aggravation. If
only it were the other way around.

Regards,

Will Hartung
([EMAIL PROTECTED])




--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to