<meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/> <meta name='google-adsense-platform-domain' content='blogspot.com'/> <!-- data-ad-client=ca-pub-4320963827702032 --> <!-- --><style type="text/css">@import url(//www.blogger.com/static/v1/v-css/navbar/3334278262-classic.css); div.b-mobile {display:none;} </style> </head><body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar.g?targetBlogID\x3d7256432\x26blogName\x3dThe+Frustrated+Programmer\x26publishMode\x3dPUBLISH_MODE_BLOGSPOT\x26navbarType\x3dBLACK\x26layoutType\x3dCLASSIC\x26searchRoot\x3dhttps://frustratedprogrammer.blogspot.com/search\x26blogLocale\x3den_US\x26v\x3d2\x26homepageUrl\x3dhttps://frustratedprogrammer.blogspot.com/\x26vt\x3d-1687486435376088425', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe", messageHandlersFilter: gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER, messageHandlers: { 'blogger-ping': function() {} } }); } }); </script>
| Sunday, August 01, 2004

I was profiling our application with optimizeIt looking for memory leaks when I noticed that the tag library DisplayTag was holding on to my lists of objects. I looked in the source and it was letting go of the list in the release() method, just like it should. I couldn't figure it out, so I called a friend who had done his homework and read the specs. He explained the behavior a lot better than the JavaDoc below:

public void release()
Called on a Tag handler to release state. The page
compiler guarantees that JSP page implementation objects
will invoke this method on all tag handlers, but there may
be multiple invocations on doStartTag and doEndTag in
between.

The spec added a little more, but its still a little vague:

Once all invocations on the tag handler are completed, the
release method is invoked on it. Once a release method is
invoked all properties, including parent and pageContext, are
assumed to have been reset to an unspecified value. The page
compiler guarantees that release() will be invoked on the
Tag handler before the handler is released to the GC.

Well, Billy explained that release() will not always be called immediately after doEndTag(). If the container wishes, it might want to wait until the next call to your tag. If this next call passes the exact same arguments, it will just invoke the tag again, without setting attributes on it. Under certain circumstances, like tag pooling, release will not be called until container shuts down.

As I was writing this entry, I looked about a bit. There is a lot of misleading information on this. Notice this article on ONJava.com:
The container also guarantees that release will be invoked on the tag handler before the end of the page.


According to the spec, this isn't true. release() will get called before the tag is GC'd, that has nothing to do with a page and its scope or rendering.

Update: Tag pooling can be turned off in Tomcat by adding the following to your CATALINA_HOME/conf/web.xml. Add this to the servlet/servlet-name='jsp' section.

<init-param>
<param-name>enablePooling</param-name>
<param-value>false</param-value>
</init-param>