David wrote:
> > I think that the lack of class unloading/reloading is the major factor
> > that will keep real sites from using JSPs. Take our site for example
> > (http://www.klgroup.com). We want a more "interactive" site, but
> > we don't want multiple sets of pages - all pages should be managed
> > using a single technology. Can JSPs do that? No, we'd end up having
> > way to many classes loaded into memory for all those mostly static
> > pages.
>
> Let's say you have 5000 most static pages (why use JSP then?), and each
> generates a big class file that takes up 50KB, that would 256MB. That's a
> lot of memory to use, but also it's really not that much these days. Heck,
> you buy a PC with 512MB of RAM for $1800 or so, and that's a reasonable
> expense I'd say for a site with 5000 pages!
As I mentioned in my original response to Jason, the memory usage is a limitation
of the early JSP prototypes, not an inherent limitation of JSP.
For instance, GNUJSP uses a particuly wasteful (heap wise) technique of
translating JSP, because GNUJSP was a quick hack.
It takes code like this
<foo>
this is a test
<bar>
and generates code that looks like this:
out.println("<foo>\r\n"+"this is a test\r\n"+"<bar>\r\n");
Note, the use of String concatenation. GNUJSP servlets end up
using this heavily, a big no-no.
A much more efficient approach is to generate character arrays, such as
char a1[]= {'<', 'f', 'o', 'o','>'};
char a2[]= {'t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't' };
char a3[] = {'<', 'b', 'a', 'r', '>'};
out.write(a1);
out.write(a2);
out.write(a3);
Note only is this faster, but it saves a duplicate heap allocation when
the OutputStream inevitably calls String.toCharArray() which creates a copy
of the internal char[] array due to the immutability of Strings.
However, this still wastes space in the JVM's constant pool, and 25k of
static data is 25k of static data, that much be loaded or unloaded with
the entire class. But, atleast it's not being multiplied by two, as
the String generation approach would cause.
The real solution is to generate code that looks like this:
out.write(getConstant(1));
out.write(getConstant(2));
out.write(getConstant(3));
where getConstant(int) looks something like this
SoftReference constantPoolRef;
public char[] getConstant(int index)
{
char[][] constants=constantPoolRef.get();
if(constants == null)
{
constants=reloadConstants();
constantPoolRef=new SoftReference(constants);
}
return constants[index];
}
public char[][] reloadConstants()
{
//code to read in the strings from some autogenerated file, could even be
// a ResourceBundle
}
With an implementation like this, heap usage is extremely efficient, the
runtime execution is faster than using String constants, and constants are
allocated in the runtime heap and can be GC'ed at any time (doesn't even require
class unloading)
The prospects for generating heavily optimized and scalable JSP are far brighter
than with template parsers, and if you are running a heavy duty system, every
kilobyte counts. For instance, you could, in the caseof 7bit/us-ascii, use byte
arrays for another 50% savings, and, in terms of GC'ing, you could allow for
a much more fine grained level of "paging out" of the constants.
-Ray
===========================================================================
To unsubscribe: mailto [EMAIL PROTECTED] with body: "signoff JSP-INTEREST".
FAQs on JSP can be found at:
http://java.sun.com/products/jsp/faq.html
http://www.esperanto.org.nz/jsp/jspfaq.html