Details
-
Improvement
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.0.0
-
None
-
None
Description
The class org.apache.struts2.views.freemarker.tags.TagModel creates a new freemarker.template.DefaultObjectWrapper for each call to unwrapParameters(Map). The problem is that that class is quite expensive to construct as the super-class does a quite bit of introspection to fill up its caches. Not only is this a lot of work, it tends to hit the Introspector class pretty hard, which internally does a lot of sychronising. In our soak performance tests this was a significant cause of blocking in our application.
The DefaultObjectWrapper (or more properly the freemarker.ext.beans.BeansWrapper class as that is actually all the TagModel is using) is actually meant to be a cache that prevents exactly this kind of slowness, so constructing a new one every time is counter-productive.
I don't have the latest source handy so I can't provide a patch, but the change is to simply replace the line:
DefaultObjectWrapper objectWrapper = new DefaultObjectWrapper();
with:
BeansWrapper objectWrapper = BeansWrapper.getDefaultInstance();
in the second line of TagModel.unwrapParameters(Map params)