JSP Tag Pooling Memory Leaks
13.8.2009 | 2 minutes of reading time
JSP custom tags were once widely used, but even still nowadays they find their way into projects. Not to mention the masses of production code using them. And almost all projects I have looked at using custom tags had the same issue. When writing JSP custom tags you have to remember the lifecycle model of a custom tag, because the container will typically pool tag instances. This is allowed and recommended by the specification, but can create lots of trouble when the tag is incorrectly written. Storing big objects in the tag instance will create a memory leak that can make your server go boom (or nothing happens because your tag pool is small and the instance is almost al time in use).Typically this sneaks by unnoticed in development environment.
The code causing this problem looks typically like this one here:
1public class MyTag extends TagSupport {
2 public Object leak;
3 public int doStartTag(){
4 leak = new BigObject();
5 }
6}
This is a problem, because the lifecycle of a pooled tag looks like this:
- load class
- create instance
- invoke setPageContext()
- invoke setters
- call doStartTag
- call possibly other tag methods depending on the tag type and return values
- call doEndTag()
- put instance in pool
when the same tag is re-requested it may start at step 3. If in the above example this tag is pooled lets say with 10 instances and 10 simultaneous requests, 10 instances are created in the pool. But after that only a few requests come in. But still 10 instances of the tag are in the pool and contain reference to the BigObject. This is a memory leak.
To avoid this always null out “transient” instance variables of the class and reload them either in setPageContext() or doStartTag(). Also note that the code inside the constructor might only be run once per tag, even when the tag is used on hundreds of pages. The amount of tag instances created (and thus also the amount of constructors invoked) depends on the container and pool settings and on the serverload.
1public class MyTag extends TagSupport {
2 public Object noLeak;
3
4 public void setPageContext(PageContext pc){
5 noLeak = new BigObject();
6 }
7
8 public int doStartTag(){
9 }
10
11 public void doEndTag(){
12 noLeak = null;
13 }
14}
Other alternatives are to improve code design and make variables as local as possible.
A relates problem is that you might find values in your tag that you don’t expect. Lets say a property is set when a certain parameter has a specific value. Now that condition was true, so the property holds an object that is not nulled out. The next usage of that tag will find the object even though the condition on the parameter is not set. This can really mess up your logic.
More articles
fromFabian Lange
Your job at codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
More articles in this subject area
Discover exciting further topics and let the codecentric world inspire you.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog author
Fabian Lange
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.