Re: Memory Usage and Garbage Collection

2003-01-15 Thread Will Hartung
Hi Steve,

The real decision you need to make is how common are the common parts of
your JSPs, and how much content is within the JSPs.

If most of your JSPs are simply blocks of content surrounded by the same
boiler plate JSP code, then perhaps it is worth while to make those JSPs a
single JSP that then loads the different content at runtime based upon the
request.

But the real consideration is simply the amount of content that you're
delivering within the JSPs.

Consider this: If you have 500 JSP's that each have 20K of text (which is
quite a bit of text if you think about it), then that's only 20MB of memory
for the content. The calculation is 500 files x 20,000 characters x 2 for
unicode (unicode characters, which Java uses, are 2 bytes).

So, using brute force, back-of-napkin calculations, 512MB of memory would
store 25000 of those documents.

Also, if your document count is mostly static from day to day, i.e. you
aren't adding large numbers of new documents each day, then you can easily
pre-compute your overall memory burden simply for the documents, and scale
appropriately.

So, I doubt the JSPs alone are causing your memory problems, it's probably
something else.

Hope this was helpful,

Regards,

Will Hartung
([EMAIL PROTECTED])


- Original Message -
From: Turoff, Steve [EMAIL PROTECTED]
To: Will Hartung [EMAIL PROTECTED]
Sent: Tuesday, January 14, 2003 10:07 AM
Subject: RE: Memory Usage and Garbage Collection


Will,

I too am experiencing memory problems and I think your explanation below
might apply to me. I'm using Tomcat 4.1 on RedHat Linux. Over the course of
a few days, I notice, (using top) that the amount of physical memory used by
the java processes continually increases until it exceeds the maximum that
I've set (-Xmx512m) and then will generate an java.lang.OutOfMemoryError in
$CATALINA_HOME/logs/localhost_log.-MM-DD.txt. I believe the problem is
that my JSPs are dynamic, but I'm not sure exactly what differentiates a
static JSP from a dynamic JSP.




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




RE: Memory Usage and Garbage Collection

2003-01-10 Thread Turoff, Steve
Will,

I too am experiencing memory problems and I think your explanation below might apply 
to me. I'm using Tomcat 4.1 on RedHat Linux. Over the course of a few days, I notice, 
(using top) that the amount of physical memory used by the java processes continually 
increases until it hits the maximum that I've set (-Xmx512m) and then will generate an 
outOfMemory error. I believe the problem is that my JSPs are dynamic, but I'm not sure 
exactly what differentiates a static JSP from a dynamic JSP.

I have several hundred JSPs - each one looks like:

!-- BEGIN SAMPLE PAGE --
jsp:useBean id=thisPage class=PHN.PHNPage scope=session /
jsp:setProperty name=thisPage property=section value=foo /

%@ include file=/templates/header.jsp %

I am body content. Some pages use the following java: 

a href=/a.pdfDocument a/a (PDF file - %= new File(/a.pdf).length()/1024 %

%@ include file=/templates/footer.jsp %
!-- END SAMPLE PAGE --


header.jsp looks something like this:

!-- BEGIN HEADER.JSP --
%
String host = http://; + request.getServerName();
String requestURI = request.getRequestURI();
String pageType = request.getParameter(pageType);
String section = thisPage.getSection(); 
%

A bunch of HTML

% if (section.equals(foo)) { %
%@ include file=/nav/foo.jsp %
% } %
!-- END HEADER.JSP --

footer.jsp is similar.

So are my JSPs dynamic? If so, can I solve my memory problems by switching them to XML 
docs and using a single JSP page (along with XSLT) to render the pages?

Thanks much for your help.

Steve

 -Original Message-
 From: Will Hartung [mailto:[EMAIL PROTECTED]]
 Sent: Friday, January 03, 2003 4:54 PM
 To: Tomcat Users List
 Subject: Re: Memory Usage and Garbage Collection
 
 
  From: Brandon Cruz [EMAIL PROTECTED]
  Sent: Friday, January 03, 2003 2:23 PM
  Subject: RE: Memory Usage and Garbage Collection
 
 
  1)For every single request to a servlet or JSP page, a new 
 instance of
 that
  class is created?  For example, if there is one JSP page 
 and ten people
  access that one page over the course of a day, 10 separate 
 instances of
 the
  same class are created and will never be gc'd until the 
 webapp or tomcat
 is
  restarted?
 
 No no no.
 
 Ever so confusing.
 
 Here's the rub.
 
 First, consider that JSP == Servlet.
 
 Second, Servlet == Java Class.
 
 When a request comes in for a Servlet, the Servlet class is 
 loaded. Then
 (assuming we're not using a Single Threaded Model Servlet), a 
 new instance
 of that Servlet is created to handle the request.
 
 These instances of the Servlet will inevitably be GC'd in time.
 
 However, what will NOT be GC'd is the CLASS of the Servlet. 
 Once the class
 is loaded, the class stays around until restart. This is because the
 ClassLoader for the Servlet hangs on to it.
 
 For most applications this is not a problem, as Servlets are roughly
 equivalent to CGI programs.
 
 However, where Servlets are similar to CGI programs, some are 
 equating JSPs
 with HTML files (or, perhaps better, SHTML files).
 
 Most normal sites would have very few CGI programs, but may 
 have loads of
 HTML or SHTML files.
 
 But, since JSPs are actually Servlets in cheap clothing, the 
 JSP == HTML
 file is not a valid assumption to make.
 
 Whereas Servlets are usually mostly just logic, JSPs tend to be mostly
 content. So, when the server loads the Servlet class 
 generated by the JSP,
 it loads and caches more content than logic.
 
 If Apache remembered and cached every HTML file that went 
 through it, you'd
 end up potentially caching your entire web tree in RAM. If 
 you happen to
 have enough RAM to support this, it's not a problem. But if 
 your content is
 growing every day, and old data doesn't go away, you will 
 eventially run
 out of RAM and Bad Things will happen.
 
 Our site has ~1200 JSPs but all told they only add up to 
 about 6MB, and
 they're static. So, if all of those managed to get sucked 
 into RAM, the
 space they would take wouldn't even make a 256MB Tomcat 
 instance blink, so
 it's not a problem for us.
 
 But another fella was generating dynamic JSPs, and would 
 thereby eventually
 starve out his heap because Tomcat wasn't expiring Servlets.
 
 The real question is whether JSPs should be considered 
 Different Enough from
 normal Servlets to warrant adding code to scavenge them.
 
 Regards,
 
 Will Hartung
 ([EMAIL PROTECTED])
 
 
 
 --
 To unsubscribe, e-mail:   
 mailto:[EMAIL PROTECTED]
 For additional commands, e-mail: 
 mailto:[EMAIL PROTECTED]
 
 
 

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




RE: Memory Usage and Garbage Collection

2003-01-05 Thread Saurabh Arora
Thanks for that explanation,
 But i was just curious to know if weakmaps or similar gc interacting
cache be used to keep the mem size in control.
 Servers with high mem size would continue to keep the cache of jsp's
for performance whereas the ones with lesser mem size would still not
give the outofmemory error.

saurabh 

 [EMAIL PROTECTED] 01/04/03 01:12AM 


On Fri, 3 Jan 2003, Saurabh Arora wrote:

 Date: Fri, 03 Jan 2003 02:33:17 -0700
 From: Saurabh Arora [EMAIL PROTECTED]
 Reply-To: Tomcat Users List [EMAIL PROTECTED]
 To: [EMAIL PROTECTED] 
 Subject: RE: Memory Usage and Garbage Collection

 Just wanted to know, does the current implementation of tomcat
4.1.18
 also has the same problem of keeping the jsp's
  in memory. or it was only present in 4.0.4


It's not a *problem* -- it's a *feature* :-).  This is one of the keys
to
maintaining good performance on repeatedly requested pages.

Yes, Tomcat 4.1.x maintains a reference to every JSP page that has
ever
been requested (same as every servlet that has ever been requested)
until
that webapp is reloaded or removed, or you shut down Tomcat.

Given this, designing webapps where you auto-generate hundreds of
different JSP pages (which was the choice of the originator of this
message thread) is not what you really want to do.  Instead, you'd want
to
use a single JSP page for each basic *style* of output (essentially
the
JSP page would be a formatting template) that pulls in the unique
information for a particular report (from the database, from XML, or
whatever) dynamically.  Then, a given webpp would likely have 5-10 JSP
pages, instead of hundreds.

Just as an example, assume that your application back-end gave you the
data you need in some XML format, and you want to offer your user the
chance to format this data in ten different ways.  If you create an
XSLT
stylesheet to transform the data for each of the ten formats, you can
do
this all with a *single* JSP page that takes an XML data source and an
XSLT stylesheet, applies the transformation, and renders the result.
(JSTL has a tag that will do all the grunt work for you.)

If you really really want to auto-generate all the reports ahead of
time,
go ahead and generate static HTML pages -- don't waste your time
generating JSP that then has to get compiled, loaded, and executed.  As
a
side benefit, the output will get served a little faster because there
is
less overhead in serving static files.

If you really really really want to generate hundreds of JSP pages,
then
plan on buying enough memory to hold them all and be done with it.
Fortunately, this is not usually a break the bank decision (I just
upgraded my development PC to a gigabyte of memory for less than $100
:-).

If you really really really really want to generate hundreds of JSP
pages,
and don't (or can't) afford the memory to hold them all, you only have
yourself to blame for the results.


 saurabh

Craig


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


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




Re: Memory Usage and Garbage Collection

2003-01-05 Thread Nikola Milutinovic
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:   mailto:[EMAIL PROTECTED]
For additional commands, e-mail: mailto:[EMAIL PROTECTED]



RE: Memory Usage and Garbage Collection

2003-01-03 Thread Andreas Probst
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:   mailto:[EMAIL PROTECTED]
For additional commands, e-mail: mailto:[EMAIL PROTECTED]




RE: Memory Usage and Garbage Collection

2003-01-03 Thread Saurabh Arora
Just wanted to know, does the current implementation of tomcat 4.1.18
also has the same problem of keeping the jsp's
 in memory. or it was only present in 4.0.4


saurabh 

 [EMAIL PROTECTED] 01/03/03 02:26PM 
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:  
mailto:[EMAIL PROTECTED]
For additional commands, e-mail:
mailto:[EMAIL PROTECTED]


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




RE: Memory Usage and Garbage Collection

2003-01-03 Thread Shapira, Yoav
Hi,
There's clearly some misconceptions on the topic of garbage collection
;)  These questions come up very often it seems, on this list and
others.

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.

You don't have to do this.  The otherObject's reference count is
increase by one when you assign it.  When the method (service() above)
returns, the reference count for otherObject is reduced by one.  If the
reference count is zero, otherObject can be garbage collected.

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

If otherObject creates local objects, they'll be GCed.  If it modifies
static objects, those objects stay in a different place anyways and
don't get GCed when otherObject does.

Back to what Craig mentioned earlier: earlier in the Java life time,
classes could get GCed themselves.  That really earns you very little,
so it was removed.  Nowadays demands on classloaders and their
hierarchies can get very complicated, so re-introducing class GC would
be difficult anyways.   

A JSP is compiled into a servlet and then loaded into memory.  Its
bytecode is present only once, and takes up relatively little space
(usually).  You won't gain much from destroying that bytecode and
de-allocating its memory.  Same thing for normal servlets obviouisly.

What you need to do is tune your garbage collection.  With some
exceptions, full GCs shouldn't run all the time.  Depending on your
collector, partial GCs can run all the time.  You'd expect that from
incremental and concurrent collectors.  If you're running on multiple
CPUs and have a parallel collector but only one System.out log, you'd
expect to see GC output there nearly all the time.

So you should start playing with your heap (-Xmx), new generation size
and ration (XX:NewSize, XX:MaxNewSize, XX:NewRatio), collector policy
(-Xincgc, -Xconcgc, XX:UseParNewGC, etc.) and other parameters to see
which gives you the best behavior.  Don't -Xmx over the physical RAM
size.  See the VM options page at:
http://java.sun.com/docs/hotspot/VMOptions.html

One principle to keep in mind is that memory is cheap, or at least
considered cheap when it comes to GC performance tuning.  The java heap
is greedy overall, and this is intended to increaser performance.
That's why it won't de-allocate space (and never return space to the OS)
until necessary with the default mark/sweep collector.

Make sure to record your verbose:gc output between runs so that you can
compare behavior.  This is not typically easy to tell by instinctive
feel. 

Yoav Shapira
Millennium ChemInformatics

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




RE: Memory Usage and Garbage Collection

2003-01-03 Thread Andreas Probst
Hi thank you,

your reply calms me down again. I guess I got a bit confused by 
the preceding discussion.

Andreas

On 3 Jan 2003 at 8:59, Shapira, Yoav wrote:

 Hi,
 There's clearly some misconceptions on the topic of garbage
 collection ;)  These questions come up very often it seems, on
 this list and others.
 
 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.
 
 You don't have to do this.  The otherObject's reference count is
 increase by one when you assign it.  When the method (service()
 above) returns, the reference count for otherObject is reduced by
 one.  If the reference count is zero, otherObject can be garbage
 collected.
 
 What about the object instances, which
 otherObject.doThisAndThat() creates? So far I've thought there
 are no live references if otherObject gets gc-ed.
 
 If otherObject creates local objects, they'll be GCed.  If it
 modifies static objects, those objects stay in a different place
 anyways and don't get GCed when otherObject does.
 
 Back to what Craig mentioned earlier: earlier in the Java life
 time, classes could get GCed themselves.  That really earns you
 very little, so it was removed.  Nowadays demands on classloaders
 and their hierarchies can get very complicated, so re-introducing
 class GC would be difficult anyways.   
 
 A JSP is compiled into a servlet and then loaded into memory. 
 Its bytecode is present only once, and takes up relatively little
 space (usually).  You won't gain much from destroying that
 bytecode and de-allocating its memory.  Same thing for normal
 servlets obviouisly.
 
 What you need to do is tune your garbage collection.  With some
 exceptions, full GCs shouldn't run all the time.  Depending on
 your collector, partial GCs can run all the time.  You'd expect
 that from incremental and concurrent collectors.  If you're
 running on multiple CPUs and have a parallel collector but only
 one System.out log, you'd expect to see GC output there nearly
 all the time.
 
 So you should start playing with your heap (-Xmx), new generation
 size and ration (XX:NewSize, XX:MaxNewSize, XX:NewRatio),
 collector policy (-Xincgc, -Xconcgc, XX:UseParNewGC, etc.) and
 other parameters to see which gives you the best behavior.  Don't
 -Xmx over the physical RAM size.  See the VM options page at:
 http://java.sun.com/docs/hotspot/VMOptions.html
 
 One principle to keep in mind is that memory is cheap, or at
 least considered cheap when it comes to GC performance tuning. 
 The java heap is greedy overall, and this is intended to
 increaser performance. That's why it won't de-allocate space (and
 never return space to the OS) until necessary with the default
 mark/sweep collector.
 
 Make sure to record your verbose:gc output between runs so that
 you can compare behavior.  This is not typically easy to tell by
 instinctive feel. 
 
 Yoav Shapira
 Millennium ChemInformatics
 



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




RE: Memory Usage and Garbage Collection

2003-01-03 Thread Craig R. McClanahan


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]




RE: Memory Usage and Garbage Collection

2003-01-03 Thread Craig R. McClanahan


On Fri, 3 Jan 2003, Saurabh Arora wrote:

 Date: Fri, 03 Jan 2003 02:33:17 -0700
 From: Saurabh Arora [EMAIL PROTECTED]
 Reply-To: Tomcat Users List [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Subject: RE: Memory Usage and Garbage Collection

 Just wanted to know, does the current implementation of tomcat 4.1.18
 also has the same problem of keeping the jsp's
  in memory. or it was only present in 4.0.4


It's not a *problem* -- it's a *feature* :-).  This is one of the keys to
maintaining good performance on repeatedly requested pages.

Yes, Tomcat 4.1.x maintains a reference to every JSP page that has ever
been requested (same as every servlet that has ever been requested) until
that webapp is reloaded or removed, or you shut down Tomcat.

Given this, designing webapps where you auto-generate hundreds of
different JSP pages (which was the choice of the originator of this
message thread) is not what you really want to do.  Instead, you'd want to
use a single JSP page for each basic *style* of output (essentially the
JSP page would be a formatting template) that pulls in the unique
information for a particular report (from the database, from XML, or
whatever) dynamically.  Then, a given webpp would likely have 5-10 JSP
pages, instead of hundreds.

Just as an example, assume that your application back-end gave you the
data you need in some XML format, and you want to offer your user the
chance to format this data in ten different ways.  If you create an XSLT
stylesheet to transform the data for each of the ten formats, you can do
this all with a *single* JSP page that takes an XML data source and an
XSLT stylesheet, applies the transformation, and renders the result.
(JSTL has a tag that will do all the grunt work for you.)

If you really really want to auto-generate all the reports ahead of time,
go ahead and generate static HTML pages -- don't waste your time
generating JSP that then has to get compiled, loaded, and executed.  As a
side benefit, the output will get served a little faster because there is
less overhead in serving static files.

If you really really really want to generate hundreds of JSP pages, then
plan on buying enough memory to hold them all and be done with it.
Fortunately, this is not usually a break the bank decision (I just
upgraded my development PC to a gigabyte of memory for less than $100 :-).

If you really really really really want to generate hundreds of JSP pages,
and don't (or can't) afford the memory to hold them all, you only have
yourself to blame for the results.


 saurabh

Craig


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




RE: Memory Usage and Garbage Collection

2003-01-03 Thread Andreas Probst
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
 

RE: Memory Usage and Garbage Collection

2003-01-03 Thread Brandon Cruz
Craig,

From what you have been saying...

1)For every single request to a servlet or JSP page, a new instance of that
class is created?  For example, if there is one JSP page and ten people
access that one page over the course of a day, 10 separate instances of the
same class are created and will never be gc'd until the webapp or tomcat is
restarted?

2)If this is true, it looks to me like any java application in the world
eventually has to be restarted as more and more people access it.  Buying
more memory would prolong the time to restart the application, but
eventually all the instances created will take up all the available RAM.  Is
this correct?

Brandon




-Original Message-
From: Craig R. McClanahan [mailto:[EMAIL PROTECTED]]
Sent: Friday, January 03, 2003 1:43 PM
To: Tomcat Users List
Subject: RE: Memory Usage and Garbage Collection




On Fri, 3 Jan 2003, Saurabh Arora wrote:

 Date: Fri, 03 Jan 2003 02:33:17 -0700
 From: Saurabh Arora [EMAIL PROTECTED]
 Reply-To: Tomcat Users List [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Subject: RE: Memory Usage and Garbage Collection

 Just wanted to know, does the current implementation of tomcat 4.1.18
 also has the same problem of keeping the jsp's
  in memory. or it was only present in 4.0.4


It's not a *problem* -- it's a *feature* :-).  This is one of the keys to
maintaining good performance on repeatedly requested pages.

Yes, Tomcat 4.1.x maintains a reference to every JSP page that has ever
been requested (same as every servlet that has ever been requested) until
that webapp is reloaded or removed, or you shut down Tomcat.

Given this, designing webapps where you auto-generate hundreds of
different JSP pages (which was the choice of the originator of this
message thread) is not what you really want to do.  Instead, you'd want to
use a single JSP page for each basic *style* of output (essentially the
JSP page would be a formatting template) that pulls in the unique
information for a particular report (from the database, from XML, or
whatever) dynamically.  Then, a given webpp would likely have 5-10 JSP
pages, instead of hundreds.

Just as an example, assume that your application back-end gave you the
data you need in some XML format, and you want to offer your user the
chance to format this data in ten different ways.  If you create an XSLT
stylesheet to transform the data for each of the ten formats, you can do
this all with a *single* JSP page that takes an XML data source and an
XSLT stylesheet, applies the transformation, and renders the result.
(JSTL has a tag that will do all the grunt work for you.)

If you really really want to auto-generate all the reports ahead of time,
go ahead and generate static HTML pages -- don't waste your time
generating JSP that then has to get compiled, loaded, and executed.  As a
side benefit, the output will get served a little faster because there is
less overhead in serving static files.

If you really really really want to generate hundreds of JSP pages, then
plan on buying enough memory to hold them all and be done with it.
Fortunately, this is not usually a break the bank decision (I just
upgraded my development PC to a gigabyte of memory for less than $100 :-).

If you really really really really want to generate hundreds of JSP pages,
and don't (or can't) afford the memory to hold them all, you only have
yourself to blame for the results.


 saurabh

Craig


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



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




Re: Memory Usage and Garbage Collection

2003-01-03 Thread Will Hartung
 From: Brandon Cruz [EMAIL PROTECTED]
 Sent: Friday, January 03, 2003 2:23 PM
 Subject: RE: Memory Usage and Garbage Collection


 1)For every single request to a servlet or JSP page, a new instance of
that
 class is created?  For example, if there is one JSP page and ten people
 access that one page over the course of a day, 10 separate instances of
the
 same class are created and will never be gc'd until the webapp or tomcat
is
 restarted?

No no no.

Ever so confusing.

Here's the rub.

First, consider that JSP == Servlet.

Second, Servlet == Java Class.

When a request comes in for a Servlet, the Servlet class is loaded. Then
(assuming we're not using a Single Threaded Model Servlet), a new instance
of that Servlet is created to handle the request.

These instances of the Servlet will inevitably be GC'd in time.

However, what will NOT be GC'd is the CLASS of the Servlet. Once the class
is loaded, the class stays around until restart. This is because the
ClassLoader for the Servlet hangs on to it.

For most applications this is not a problem, as Servlets are roughly
equivalent to CGI programs.

However, where Servlets are similar to CGI programs, some are equating JSPs
with HTML files (or, perhaps better, SHTML files).

Most normal sites would have very few CGI programs, but may have loads of
HTML or SHTML files.

But, since JSPs are actually Servlets in cheap clothing, the JSP == HTML
file is not a valid assumption to make.

Whereas Servlets are usually mostly just logic, JSPs tend to be mostly
content. So, when the server loads the Servlet class generated by the JSP,
it loads and caches more content than logic.

If Apache remembered and cached every HTML file that went through it, you'd
end up potentially caching your entire web tree in RAM. If you happen to
have enough RAM to support this, it's not a problem. But if your content is
growing every day, and old data doesn't go away, you will eventially run
out of RAM and Bad Things will happen.

Our site has ~1200 JSPs but all told they only add up to about 6MB, and
they're static. So, if all of those managed to get sucked into RAM, the
space they would take wouldn't even make a 256MB Tomcat instance blink, so
it's not a problem for us.

But another fella was generating dynamic JSPs, and would thereby eventually
starve out his heap because Tomcat wasn't expiring Servlets.

The real question is whether JSPs should be considered Different Enough from
normal Servlets to warrant adding code to scavenge them.

Regards,

Will Hartung
([EMAIL PROTECTED])



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




RE: Memory Usage and Garbage Collection

2003-01-03 Thread Craig R. McClanahan


On Fri, 3 Jan 2003, Brandon Cruz wrote:

 Date: Fri, 3 Jan 2003 16:23:24 -0600
 From: Brandon Cruz [EMAIL PROTECTED]
 Reply-To: Tomcat Users List [EMAIL PROTECTED],
  [EMAIL PROTECTED]
 To: Tomcat Users List [EMAIL PROTECTED]
 Subject: RE: Memory Usage and Garbage Collection

 Craig,

 From what you have been saying...

 1)For every single request to a servlet or JSP page, a new instance of that
 class is created?

NO!  It's exactly the opposite -- the same instance gets reused every
time.

  For example, if there is one JSP page and ten people
 access that one page over the course of a day, 10 separate instances of the
 same class are created and will never be gc'd until the webapp or tomcat is
 restarted?

 2)If this is true, it looks to me like any java application in the world
 eventually has to be restarted as more and more people access it.  Buying
 more memory would prolong the time to restart the application, but
 eventually all the instances created will take up all the available RAM.  Is
 this correct?


The point I was trying to make is that code you *call* from your servlets
and JSPs can create memory leaks, and there's not necessarily anything
that you (as the author of the servlet or JSP) page can do about it.  You
can't even tell that it's happening unless you have access to the source
code of the classes you're calling.

Assume that you implement something like the complex example from my
previous mail, and every call to the getOtherObject() method specifies a
different id value.  The old OtherObject instances will *not* be GC'd,
because there are live references to them -- even if they are not in your
servlet, they still exist in the JVM.  And the fact that there is only one
instance of your servlet is not relevant to this memory leak, because it
is not your servlet instances that are being accumulated.

It is not good enough to just release references in your servlet when you
are through with an object.

 Brandon

Craig


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




Re: Memory Usage and Garbage Collection

2003-01-03 Thread Hanasaki JiJi
The same servlet gets called everytime?  Isn't this container 
implementation specific (Although functionally it SHOULD appear to be 
the same servlet)?  For example, couldn't a container do pooling or load 
balancing.

Craig R. McClanahan wrote:

On Fri, 3 Jan 2003, Brandon Cruz wrote:



Date: Fri, 3 Jan 2003 16:23:24 -0600
From: Brandon Cruz [EMAIL PROTECTED]
Reply-To: Tomcat Users List [EMAIL PROTECTED],
[EMAIL PROTECTED]
To: Tomcat Users List [EMAIL PROTECTED]
Subject: RE: Memory Usage and Garbage Collection

Craig,


From what you have been saying...


1)For every single request to a servlet or JSP page, a new instance of that
class is created?



NO!  It's exactly the opposite -- the same instance gets reused every
time.



For example, if there is one JSP page and ten people
access that one page over the course of a day, 10 separate instances of the
same class are created and will never be gc'd until the webapp or tomcat is
restarted?

2)If this is true, it looks to me like any java application in the world
eventually has to be restarted as more and more people access it.  Buying
more memory would prolong the time to restart the application, but
eventually all the instances created will take up all the available RAM.  Is
this correct?




The point I was trying to make is that code you *call* from your servlets
and JSPs can create memory leaks, and there's not necessarily anything
that you (as the author of the servlet or JSP) page can do about it.  You
can't even tell that it's happening unless you have access to the source
code of the classes you're calling.

Assume that you implement something like the complex example from my
previous mail, and every call to the getOtherObject() method specifies a
different id value.  The old OtherObject instances will *not* be GC'd,
because there are live references to them -- even if they are not in your
servlet, they still exist in the JVM.  And the fact that there is only one
instance of your servlet is not relevant to this memory leak, because it
is not your servlet instances that are being accumulated.

It is not good enough to just release references in your servlet when you
are through with an object.



Brandon



Craig


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



--
=
= Management is doing things right; leadership is doing the =
=   right things.- Peter Drucker=
=___=
= http://www.sun.com/service/sunps/jdc/javacenter.pdf   =
=  www.sun.com | www.javasoft.com | http://wwws.sun.com/sunone  =
=


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




RE: Memory Usage and Garbage Collection

2003-01-03 Thread Noel J. Bergman
 Instead, you'd want to use a single JSP page for each basic *style*
 of output (essentially the JSP page would be a formatting template)
 that pulls in the unique information for a particular report (from
 the database, from XML, or whatever) dynamically.

For example, with the web site for The Mahogany Man
(http://www.the-mahogany-man.com), the entire catalog is a single JSP page.
There are 100s of items in the catalog.

--- Noel


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




RE: Memory Usage and Garbage Collection

2003-01-03 Thread Noel J. Bergman
 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:   mailto:[EMAIL PROTECTED]
For additional commands, e-mail: mailto:[EMAIL PROTECTED]




Re: Memory Usage and Garbage Collection

2003-01-02 Thread Craig R. McClanahan


On Thu, 2 Jan 2003, Brandon Cruz wrote:

 Date: Thu, 2 Jan 2003 16:16:23 -0600
 From: Brandon Cruz [EMAIL PROTECTED]
 Reply-To: Tomcat Users List [EMAIL PROTECTED],
  [EMAIL PROTECTED]
 To: Tomcat Users List [EMAIL PROTECTED]
 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:[EMAIL PROTECTED]
For additional commands, e-mail: mailto:[EMAIL PROTECTED]




RE: Memory Usage and Garbage Collection

2003-01-02 Thread Brandon Cruz
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:[EMAIL PROTECTED]]
Sent: Thursday, January 02, 2003 6:12 PM
To: Tomcat Users List; [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
 Reply-To: Tomcat Users List [EMAIL PROTECTED],
  [EMAIL PROTECTED]
 To: Tomcat Users List [EMAIL PROTECTED]
 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:[EMAIL PROTECTED]
For additional commands, e-mail:
mailto:[EMAIL PROTECTED]



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




Re: Memory Usage and Garbage Collection

2003-01-02 Thread Julian Löffelhardt
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 [EMAIL PROTECTED]
To: Tomcat Users List [EMAIL PROTECTED]; [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
  Reply-To: Tomcat Users List [EMAIL PROTECTED],
   [EMAIL PROTECTED]
  To: Tomcat Users List [EMAIL PROTECTED]
  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:[EMAIL PROTECTED]
 For additional commands, e-mail:
mailto:[EMAIL PROTECTED]




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




RE: Memory Usage and Garbage Collection

2003-01-02 Thread Craig R. McClanahan


On Thu, 2 Jan 2003, Brandon Cruz wrote:

 Date: Thu, 2 Jan 2003 19:04:55 -0600
 From: Brandon Cruz [EMAIL PROTECTED]
 To: Tomcat Users List [EMAIL PROTECTED]
 Cc: [EMAIL PROTECTED]
 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:[EMAIL PROTECTED]]
 Sent: Thursday, January 02, 2003 6:12 PM
 To: Tomcat Users List; [EMAIL PROTECTED]
 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 [EMAIL PROTECTED]
  Reply-To: Tomcat Users List [EMAIL PROTECTED],
   [EMAIL PROTECTED]
  To: Tomcat Users List [EMAIL PROTECTED]
  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

Re: Memory Usage and Garbage Collection

2003-01-02 Thread Craig R. McClanahan


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

 Date: Fri, 3 Jan 2003 02:01:58 +0100
 From: Julian Löffelhardt [EMAIL PROTECTED]
 Reply-To: Tomcat Users List [EMAIL PROTECTED]
 To: Tomcat Users List [EMAIL PROTECTED]
 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 [EMAIL PROTECTED]
 To: Tomcat Users List [EMAIL PROTECTED]; [EMAIL PROTECTED]
 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 [EMAIL PROTECTED]
   Reply-To: Tomcat Users List [EMAIL PROTECTED],
[EMAIL PROTECTED]
   To: Tomcat Users List [EMAIL PROTECTED]
   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