about greg
outofmemory: greg's blog
projects


Archive for March, 2008

Use the “default” Attribute of c:out

Saturday, March 22nd, 2008

One of the most common operations in the JSTL framework is the <c:out> tag:

<c:out value="${name}" />

In applications that use this tag heavily, there is a high memory cost when you do not specifying the default attribute. The cost occurs when a NullAttributeException is thrown by the JSTL framework when an attribute is missing while evaluating the tag attributes. The creation and try/catch of the NullAttributeException uses 1,250 bytes of memory per tag instance, all of which can be avoided by simply providing an empty default:

<c:out value="${name}" default="" />

Although 1,250 bytes may seem fairly innocuous, imagine the costs magnified in the example of a multi-row, multi-cell table with potentially hundreds of renderings. Then you’re talking about serious memory churn for your transaction. So if you are using <c:out> tags in a exponential capacity (i.e. nested in a <c:foreach> tag), then be sure to implement a default, even if it is an empty space.

You might ask “But then why don’t I have to implement the escapeXml attribute?”

The answer is because the escapeXml attribute requires a boolean value. The evaluateExpressions() method of the OutTag code does not have to check for null because the when the value is evaluated it is converted to a Boolean object. The Boolean is then evaluated and cannot result in a NullAttributeException.

Custom Tags and BodyContentImpl

Saturday, March 22nd, 2008

A colleague of mine recently asked me about a past performance issue I worked on revolving around the use of “body content” in custom tag libraries. Body content is best described in by the following examples:

Tag with Body Content:

<myTag:foo name="name1">Some body content...<myTag:foo/>

Tag without Body Content:

<myTag:foo name="name1" />

When you design a tag to manipulate that body content, you end up internally using the class org.apache.jasper.runtime.BodyContentImpl. This is the source of the performance concern because this class initializes a char array to a length of 512 each time it is instantiated [source: jasper-runtime.jar in Tomcat 5.5]. Then it contains a growth strategy for when your body content expands outside of that container.

The problem comes when you inadvertently support body content when your usage doesn’t need it to. In one application that makes heavy use of custom tags, I saw a small percentage of instances where the tag was used with body content. On some pages, there were 30-40 tag instances, all of which were not using any body content. Which meant most of the time we were burning that 512 character array for no good reason.

Now 40 instances of wasting 1,024 bytes (512 x 2 bytes per char) on a page might not be a big deal, but in older application servers (WebSphere 5.0, for example), this character array buffer size was set to 8,192, which meant over 16kb per tag instance was being wasted. In an application that heavily uses tags, this was a huge waste of memory in the JVM. Not to mention if these tags aren’t pooled, then you’re creating these wasted blocks of memory every time the page is executed.

The solution in general is to evaluate the usage of your tag. If your tag needs body content support, but most of the instances do not actually supply that content, consider splitting the code into two tags: one that supports body content and one that does not. Another approach was to attempt to cache some of the tags using application server settings, but I have some details on that I will share some other time.

WAS Database Connection Settings: Shared vs. Unshared

Friday, March 21st, 2008

My colleague Phil gave me a simple but effective breakdown of the difference between these two settings in WebSphere Application Server. Here he describes the shared setting:

Shareable tells the WAS container, when a servlet transport thread closes a connection, don’t actually put that connection back in the pool. Instead, keep it in some local context so that the thread can get access to it when it asks again during the processing of this request. Then finally, when the request is completed, then put the connection back in the pool.

Shareable is an optimization. You would use this for connections which you know will be used many times during processing of a single request. WPS database connections are a good example. We always recommend the number of WPS portal database connections equal the number of web container thread pool size to avoid queuing for portal database connections. I’ve never seen an application database connection that would need to gain from using shareable connections.

The downside of shareable is that if you use it when you don’t need it, you need a larger pool of connections than you would with unshareable connections in order to avoid a connection bottleneck since each thread is holding a connection for a longer period of time.

He goes on to describe the unshared setting:

Unshareable has the opposite behavior. When a thread closes a connection, the thread puts the connection back in the pool.

As an aside if you don’t have a resource-ref defined with shareable/unshareable property and/or don’t use this ref name in the code - you will get shareable by default - with a warning in wps.err/out. In this circumstance your pool size may be causing queuing if the size of the connection pool is less than the size of the thread pool. We suggest to use a resource-ref and set this to unshareable for applications.