Summary: | The forEach JSTL tag doesn't release items | ||
---|---|---|---|
Product: | Taglibs | Reporter: | Alex <81bas> |
Component: | Standard Taglib | Assignee: | Tomcat Developers Mailing List <dev> |
Status: | RESOLVED WONTFIX | ||
Severity: | normal | CC: | Sergiusz.Brzezinski, taras.tielkes |
Priority: | P3 | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Hardware: | All | ||
OS: | other |
Description
Alex
2003-12-18 11:59:37 UTC
There's been a thread about this issue in the mailing list: http://nagoya.apache.org/eyebrowse/BrowseList?listId=43&by=thread&from=682274 CC'ing the taglibs-dev address to all Standard bugs. From the tag author's point of view I believe that the JSTL tag handler's are doing the right thing. In the forEach tag, the release method sets the items to null. The tag handler instance can be reused if tag pooling is enabled and if another custom action uses the same set of attributes. The strut's tags explicitly set items to null in the doEndTag() method. The struts implementation violates the tag pooling contract and can end up needlessly destroying and creating items between invocations of doStartTag and doEndTag. Now, on to how the container manages the jsp lifecycle and when release is actually called. If you look at the Tomcat 5 jasper (jsp) implemenation you will see a Generator that generates the java servlet source code given a jsp. This Generator creates a _jspDestroy() method. Here is the method from one of my generated servlet files: ---- public void _jspDestroy() { _jspx_tagPool_c_out_value_nobody.release(); _jspx_tagPool_c_out_value_escapeXml_nobody.release(); } ---- When _jspDestroy() is invoked it calls all the tag handlers in the pool and tells them to invoke their release methods. Now on to when the _jspDestroy() method is invoked. Every servlet that was generated from a jsp page extends org.apache.jasper.runtime.HttpJspBase. The HttpJspBase has a destroy() method that invokes _jspDestroy(). HttpJspBase.destroy() is invoked whenever Servlet.destroy() is and follows the servlet lifecycle. Now on to the tricky part, the container itself determines when the servlet will be taken out of service and can do so for various reasons. It would be difficult to determine when it has done so and when the object references are actually freed. It would be interesting to see your profiler results when using a different container. There is a good discussion on container behavior, lifecycle, and tag pooling available in this bug report: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16001 If you find that you are having issues as a result of the container tag pooling, uou can turn it off in Tomcat by setting the init parameter "enablePooling" to "false" in your global $CATALINA_BASE/conf/ web.xml. This issue seems more in the realm of the container and how it manages objects and tag pools. It must be a bug. I have developed a big system that uses many JSTL Tags, and after some hours I have OutOfMemory error. I used a profiler and discovered that the SetTag and others tags (some that I developed) was not releasing objects in release() method. Now I'm implementing TryCatchFinally interface in all tags I developed and for SetTag I extended it and implemented TryCatchFinally too. (In reply to comment #0) > The forEach tag after pooling doesn't allow items to be garbage collected. > JVM profiler indicates, that org\apache\taglibs\standard\tag\el\core\ForEachTag > class 'items' member still have references to objects, even after all sessions > timeout and garbage collector run. The same thing happens with 'c:set' tags - > they holds references to objects in 'target' member. May be it is a bug in > Tomcat with invoke 'release()' method? I try to use all Tomcat 4.1.x versions. > They all acts the same. After this I try to use Struts 'logic:iterate' tag, and > all objects will be garbage collected successfully. Based on Justyna's reply, marking this as WONTFIX. The new location for the nagoya link referenced here seems to be http://issues.apache.org/bugzilla/show_bug.cgi?id=16001 |