1 Funny Thing Not to Forget While Profiling on Tomcat

Unless you write only very small apps, memory leaks are unfortunately common pain you’ll have to face earlier or later. Especially if your code will be running in some sort of a container that uses pools of reusable threads,  you should think twice if you really need this ThreadLocal and if you take the proper care to clean all the references you are holding as soon as you don’t need them any more.

When being careful is not enough

Well, but that’s theory. One day you will forget, or – just start using that useful library, which uses someone other’s library (and probably not just one) and suddenly, there’s a fair amount of code on your classpath, that you are not in real control of.

Anyway, at some point, you will most likely end up using profiler to find out what part of your app is eating your precious memory without having an obvious reason to do so.

Memory Leak

Memory Leak

Cat does what is good for cat

I love cats, they are little cute standalone entities and they always do what they consider best for them. Tomcat is not different – maybe not cute, maybe not little, but does what it things it needs to do. I don’t use it much (Grizzly or Jetty are mostly sufficient for development), so was not aware of one (actually nice) feature it has since version 6.0.24.

Yes, it’s awkward, but I will share it, maybe it saves someone other’s time. I spent an hour of deploying, sending requests and undeploying small sample web-app with a script while watching memory consumption, forcing garbage collection and scratching my head what is wrong. I was told there is a memory leak and I did not see it.

And here’s why. The nice feature I referred to above is memory leak protection and it is enabled by default with your fresh installation. I was somehow aware of the detection, after all, there was a SEVERE warning in the server log. But I did not read it till the end, where it claims:

 Simply said – and it really does what it promises! I was pleasantly surprised how efficient this works  – the application really had a leak and even if I was re-deploying like crazy, everything looked smooth (except for the logs of course).

How to avoid this

No matter how impressive this feature might be in case you have a leaking application, you know it, but are forced to defer the solution after some other critical tasks are done – especially in a typical development workflow where you re-deploy often, in general you want to be aware of a potential memory issue.

Experience is the name everyone gives to their mistakes,

said Oscar Wilde. So, in order to help you not to repeat my experience, here comes the informational part of this post – how to turn this (otherwise probably often useful) behaviour off.

Edit the conf/server.xml file and find the part, where listeners are registered:

 

And comment out (or delete, if you prefer) the JreMemoryLeakPreventionListener and ThreadLocalLeakPreventionListener (those two are defying different types of leaks in a different way, you can read more on this on Tomcat’s wiki page), restart the server and voilà, if you keep re-deploying your leaky app, you will see the allocated memory growing and after certain amount of turns, Tomcat gives up.

The leak is detected, proved… and now you have to get rid of it. Oh, how I wish this would be equally easy as the stuff above!

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *