> Jason Hunter wrote:
> > > 2. The memory argument was a particularly memorable straw man.
> >
> > It's interesting you say that right after Tom Reilly wrote:
> >
> >   My main concern is memory consumption. Someone else pointed out
> >   that memory is still fairly cheap, but in general I dislike
> >   an architecture where things can never be unloaded from memory.
> >
> > Considering that some people view it as a problem, it belongs in an
> > article titled "The Problems with JSP".

But it's not a problem with the JSP spec, it's a problem with the
implementations.  It's like claiming a slow VM implementation is
a problem with the Java spec, and not with that particular VM.


Here is the relevent JSP implementation in Tomcat/Jasper that
references HTML character data, and my simple (untested, I just wrote
it in this message) patch to solve your problem in JDK1.2 (JDK1.1 is
also possible with a resource manager, and thread to expire the cache)


---ORIGINAL CODE---



private final String getStringVar() {
        return "_jspx_html_data["+stringId+"]";
}

private final void generateRef(ServletWriter writer) {
        if (stringId == 0)
            writer.println("static char[][] _jspx_html_data = null;");
}

private final void generateInit(ServletWriter writer) {
        if (stringId == 0) {
            String name = writer.quoteString(fileName);
            writer.println("ObjectInputStream oin = null;");
            writer.println("int numStrings = 0;");
            writer.println("try {");
            writer.pushIndent();
            writer.println("FileInputStream fin = new FileInputStream("+name+");");
            writer.println("oin = new ObjectInputStream(fin);");
            writer.println("_jspx_html_data = (char[][]) oin.readObject();");
            writer.popIndent();
            writer.println("} catch (Exception ex) {");
            writer.pushIndent();
            writer.println("throw new JasperException(\"Unable to open data file\");");
            writer.popIndent();
            writer.println("} finally {");
            writer.pushIndent();
            writer.println("if (oin != null)");
            writer.pushIndent();
            writer.println("try { oin.close(); } catch (IOException ignore) { }");
            writer.popIndent();
            writer.popIndent();
            writer.println("}");
        }
 }

private final void generatePrint(ServletWriter writer) {
        writer.println("out.print("+getStringVar()+");");
        vector.addElement(chars);
}


---ALTERED CODE---


private final String getStringVar() {
        return "getString("+stringId+")";
}


private final void generateRef(ServletWriter writer) {
        if (stringId == 0)
        {
            writer.println("static SoftReference _jspx_html_data = null;");
            writer.println("static String charDataFilename = null; ");

            writer.println("final public char[][] loadCharData() {");

            writer.println("ObjectInputStream oin = null;");
            writer.println("int numStrings = 0;");
            writer.println("try {");
            writer.pushIndent();
            writer.println("FileInputStream fin = new 
FileInputStream(charDataFilename);");
            writer.println("oin = new ObjectInputStream(fin);");
            writer.println("_jspx_html_data = new SoftReference(oin.readObject());");
            writer.popIndent();
            writer.println("} catch (Exception ex) {");
            writer.pushIndent();
            writer.println("throw new JasperException(\"Unable to open data file\");");
            writer.popIndent();
            writer.println("} finally {");
            writer.pushIndent();
            writer.println("if (oin != null)");
            writer.pushIndent();
            writer.println("try { oin.close(); } catch (IOException ignore) { }");
            writer.popIndent();
            writer.popIndent();
            writer.println("return (char[][])_jspx_html_data.get(); }");


            writer.println("final public char[] getString(int id) {");
            writer.println("char[][] data = _jspx_html_data.get(); ");
            writer.println("if(data == null) data = loadCharData(); ");
            writer.println("return data[id]; ");
            writer.println("}");
}

private final void generateInit(ServletWriter writer) {
        if (stringId == 0) {
            String name = writer.quoteString(fileName);
            writer.println("charDataFilename = "+name+";");
            writer.println("loadCharData(); ");

        }
 }


private final void generatePrint(ServletWriter writer) {
        writer.println("out.print("+getStringVar()+");");
        vector.addElement(chars);
}


---END CODE---


This patch simply uses a SoftReference to store the loaded character arrays
so that they can be GC'ed at any time, and reloaded as neccessary. Probably
needs some synchronization thrown in around the character data reference
to prevent two threads loading at the same time, but you get the
general picture.


This is purely an implementation issue, and a rather trivial one at that.

-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

Reply via email to