Hi there, while hunting down a memory leak (it turned out that some servlets didn't release PageContexts after use) I came across some places in tomcat which are a bit memory inefficent.
(I'm talking about Tomcat 5.5 SVN as of tuesday or yesterday.) The root cause (but not the problem) is that PageContexts are pooled in JspFactoryImpl. The first interesting spot is the BodyContentImpl[] outs member of PageContextImpl. It will only grow over time and it will never release the BodyContentImpls stored in there. As PageContexts are pooled, a single PageContext instance gets used by a lot of different JSPs (possibly all JSPs present in the app). The next interesting spot is the char[] cb member of BodyContentImpl it will also only grow over time and never release the space occupied by the buffer. Let's consider a JSP with a single BodyTag which will buffer a significant amount of data (say 1 MB). Over time, all PageContextImpls.out[0].cb-s will grow to this size. The JspFactoryImpl's PageContext pool contains up to 100 PageContexts, so I may end up with 100 MB of memory which is basically unused. I patched Tomcat to re-initialize PageContextImpl.outs on release(). This should increase memory efficiency significantly. Second, I re-initialized BodyContentImpl.cb[] on clear() - this seems superfluous but I found tags in the pools which still held BodyContentImpls as bodyContent therefore possibly locking lots of memory. Third, I let JspWriterImpl null it's cb on recycle() since I also found some of these lingering around and still holding parts of the output. The last two steps might be unneccessary if we could prevent that tags in the pools still hold BodyContents (as far as BodyTagSupport.bodyContent is involved). What do you think about this issue? Bye, Tino. PS: Proposed patch attached.
Index: src/share/org/apache/jasper/runtime/PageContextImpl.java =================================================================== --- src/share/org/apache/jasper/runtime/PageContextImpl.java (revision 356603) +++ src/share/org/apache/jasper/runtime/PageContextImpl.java (working copy) @@ -203,7 +203,8 @@ autoFlush = true; request = null; response = null; - depth = -1; + outs = new BodyContentImpl[0]; + depth = -1; baseOut.recycle(); session = null; @@ -706,9 +707,7 @@ depth++; if (depth >= outs.length) { BodyContentImpl[] newOuts = new BodyContentImpl[depth + 1]; - for (int i=0; i<outs.length; i++) { - newOuts[i] = outs[i]; - } + System.arraycopy(outs, 0, newOuts, 0, outs.length); newOuts[depth] = new BodyContentImpl(out); outs = newOuts; } Index: src/share/org/apache/jasper/runtime/BodyContentImpl.java =================================================================== --- src/share/org/apache/jasper/runtime/BodyContentImpl.java (revision 356603) +++ src/share/org/apache/jasper/runtime/BodyContentImpl.java (working copy) @@ -468,6 +468,9 @@ throw new IOException(); } else { nextChar = 0; + // dispose old buffer since it might have become HUGE + bufferSize = Constants.DEFAULT_TAG_BUFFER_SIZE; + cb = new char[bufferSize]; } } Index: src/share/org/apache/jasper/runtime/JspWriterImpl.java =================================================================== --- src/share/org/apache/jasper/runtime/JspWriterImpl.java (revision 356603) +++ src/share/org/apache/jasper/runtime/JspWriterImpl.java (working copy) @@ -98,6 +98,7 @@ flushed = false; closed = false; out = null; + cb = null; nextChar = 0; response = null; }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]