Search code examples
javatomcatout-of-memoryjsp-tags

Effect of LIMIT_BUFFER=true flag in Tomcat


I am running my application in Tomcat and I am getting OutofMemory error due to char array. I referred Tomcat's bug report about this error. Now I decided to add org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true in catalina.properties

My question is,

1.What are the side effects after setting this value?

2.What are the values it will clear (Will it clear values like session id)?


Solution

  • According to documentation available on Apache Tomcat Configuration,

    org.apache.jasper.runtime. BodyContentImpl.LIMIT_BUFFER

    If true, any tag buffer that expands beyond org.apache.jasper.Constants.DEFAULT_TAG_BUFFER_SIZE will be destroyed and a new buffer created of the default size.

    If not specified, the default value of false will be used.

    The documentation clearly refers to tag buffer.

    From the source reference,

    Each time you use a taglib tag on your JSP page like a <c:set> JSTL tag or really any tag (except the <jsp:*> tags as they are not really “tags” as such and handled differently), a char buffer will be set up to receive the body of that tag. The Servlet/JSP specs demand that there be no limit to the size of a tag’s body, so this buffer can grow infinitely. Additionally, if you nest a tag inside another tag, an additional buffer is set up for the nested tag, and so on. These buffers are all maintained in a stack in the PageContext, but never actually dereferenced. Because of this, all these character buffers will contiue to live and be re-used by later requests.

    What LIMIT_BUFFER does is to force Tomcat to discard the buffer before each usage if it’s larger than the default size (512 characters) and allocate a new buffer of the default size (which may of course grow if it’s not enough to handle the tag body).

    When is this relevant

    This is mainly an issue if you have tags with very large bodies. For instance, 400 worker-threads with an average tag nesting depth of 3 = 400*3*512 =~ 614 KB. But say you’re using tiles and you have a page that’s 1 MB large and 5 levels of templates. Then you’re looking at 2 GB of memory indefinitely allocated. And you have to consider the worst case since eventually, every worker-thread will have served that one large page at least once and without LIMIT_BUFFER, once those buffers have been sized up, they will never size down.

    Probably it seems like tomcat caches the huge tags data, and store it. If the pages in your application are really big, then this might grow indefinitely. Setting this property will probably not cache complete tags/html data. Large JSP page requests can fill up memory.

    As per documentation, it does seems like it caches session id.

    This was the issue reported, but seems like fixed.

    Few more data to read here, here.