Spring’s Web MVC – Redirect to the Memory Leak
They say that one rock can cause an avalanche. Lately, one of my Colleagues, Marcin Radoszewski, gave me such a rock. You’ll probably never guess what it is, but there is a chance, that you use it in many of your Web Applications. Allow me to introduce this rock to you.
You probably well know redirect after post pattern. Using Spring Framework you have few ways to implement it, let’s focus on one of them, returning the target URL as the String with redirect: prefix.
Suppose that we have controller using this method of redirecting, and we have to pass some parameters during the redirect, let it be some entity ID for example:
@RequestMapping(method = RequestMethod.POST) public String onPost(...) { ... return "redirect:form.html?entityId=" + entityId; }
As you see, our rock doesn’t look dangerous, it even doesn’t look suspicious – What the heck is wrong with that?! – you may ask. Well, to explain that, we have to take a look at the way how Spring Framework handles the value returned by you.
You may start from reading Resolving views in Spring Framework documentation, and then take a closer look at the source code of AbstractCachingViewResolver, which is base class for many different View Resolvers in Spring, including: JSP, FreeMarker, Velocity, Jasper Reports, Tiles and XSLT view resolvers.
When resolveViewName method is called on AbstractCachingViewResolver it uses HashMap based view cache to speed up view resolving in the future calls, and cache key is by default created using view name and current locale.
Now to the clue – when you use the above method of redirecting, Spring Framework uses the whole String returned from your controller’s method as the view name, including all parameters included in the target URL. Each time you perform the redirect, the parameters may vary, thus such a redirect will leave one additional entry in view cache of AbstractCachingViewResolver, causing memory leak.
How soon that will kill my application? – you may ask. That depends on the amount of memory assigned to JVM, and the number of performed redirects – I’ve made some tests using: -Xmx64M option, with simple application build from only one controller – see this example. After about 76400 redirects the application died with OutOfMemoryError: Java heap space.
Reference: Spring’s Web MVC – Redirect to the Memory Leak from our JCG partner Michal Jastak at the Warlock’s Thoughts blog.
Interesting find. Has there been a JIRA issue entered for this? I know that I have used this in the past, but it never has affected me as the number of url variations has been rather limited.
Yes, see: https://jira.springsource.org/browse/SPR-10065
good,Learn something!