Hello Tomcat (Jasper) developers,

in our project we have a serious memory problem (perm gen space) related
to JSP tag files: The class generated from the tag file gets loaded for
every JSP the tag is placed on. So if you put such a tag on i.e. 8000
JPSs, the tag class will seriously pollute the perm gen space. The
problem gets even worse, if you have a great number of tags used nearly
on every singe page. (You can trace class loading by starting the VM
with the options "-XX:+TraceClassLoading -XX:+TraceClassUnloading" and
see what I mean).

I traced down the problem in the Jasper sources and found out that even
though the container is configured not to re-load JSPs, a new instance
of a JspCompilationContext is used for every JSP. This
JspCompilationContext holds a reference to a JasperLoader (which is null
in the beginning and a new instance is created by the
JspCompilationContext on demand). Thus a new JasperLoader (=a new
ClassLoader) is used for every JSP. As tagfiles of tags placed on this
JSP get loaded via the same ClassLoader as the JSP, the class of the
same tag placed on different JSPs gets loaded via different
ClassLoaders.

There is no problem with Java-coded tags, as those get loaded by the
parent class loader and the JasperLoaders delegate to it's parent if the
class-name does not start with "org.apache.jsp".

I perfectly understand that loading each JSPs via a different
ClassLoader is necessary if you want to be able to reload the JSP-class,
but if the reloading-feature is turned off (development=false), I don't
see the need for a new ClassLoader for each JSP/tag.

It's the first time I took a look into the Tomcat sources and surely
I've missed an important point, so please excuse my silly question: But
wouldn't it be possible to re-use the ClassLoader if reloading is turned
off? I attached a simple (dirty hack) patch to illustrate what I mean.
(I don't think a static map is really a good idea here, but it a first
shot to show you what I mean)

I've already filed a bugreport for this some days ago:
http://issues.apache.org/bugzilla/show_bug.cgi?id=43878


christoph
Index: java/org/apache/jasper/JspCompilationContext.java
===================================================================
--- java/org/apache/jasper/JspCompilationContext.java   (Revision 602816)
+++ java/org/apache/jasper/JspCompilationContext.java   (Arbeitskopie)
@@ -25,6 +25,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.servlet.ServletContext;
 import javax.servlet.jsp.tagext.TagInfo;
@@ -91,6 +92,9 @@
     protected boolean protoTypeMode;
     protected TagInfo tagInfo;
     protected URL tagFileJarUrl;
+    
+    protected static Map<String, URLClassLoader> contextName2jspLoader = 
+       new ConcurrentHashMap<String, URLClassLoader>();
 
     // jspURI _must_ be relative to the context
     public JspCompilationContext(String jspUri,
@@ -176,11 +180,22 @@
 
     public ClassLoader getJspLoader() {
         if( jspLoader == null ) {
-            jspLoader = new JasperLoader
-            (new URL[] {baseUrl},
-                    getClassLoader(),
-                    rctxt.getPermissionCollection(),
-                    rctxt.getCodeSource());
+               
+            jspLoader = 
contextName2jspLoader.get(context.getServletContextName());
+
+            if (jspLoader == null) {
+                jspLoader = new JasperLoader
+                (new URL[] {baseUrl},
+                        getClassLoader(),
+                        rctxt.getPermissionCollection(),
+                        rctxt.getCodeSource());
+              if (!this.options.getDevelopment()) {
+                 contextName2jspLoader.put(context.getServletContextName(), 
jspLoader);
+              }
+            }
+               
+               
+               
         }
         return jspLoader;
     }
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to