I got this very interesting information regarding memory usage and OutOfMemoryException in servlets and JSP in my mail. The information comes from a very old mail thread archive hosted at mail-archive.com. It is really amazing that this ancient mail thread is still relevant after so many years.
We had a discussion just like this last week on a very similar topic. The end result was that person didn’t understand the JSP/servlet lifecycle and was hanging onto memory that they expected they freed up but didn’t.
Here are some good to live by rules for Servlets/JSP:
1. Never use instance variables (i.e. variables declared outside of a method as part of a class) – practically speaking they are never freed
2. Be careful with what you put into a session. Sessions generally last 30 minutes past the last request, giving a big lag between memory being needed and memory being available for others
Also, a few other notes that most people miss with Java:
1. If Java throws an OutOfMemoryException, there is no more memory to collect. Java guarantees that before the exception is thrown the garbage collector has run. If you get these exceptions then you still have references to the memory.
2. Static variables hold their memory as long as the class is loaded in memory (practically speaking, for the life of the application) If you want to test if the memory is being consumed by the API, create a simple application that calls the API a few times, checking the available memory in between the calls (use the System class).
Scenario 1 : If Java throws an OutOfMemoryException, there is no more memory to collect. Java guarantees that before the exception is thrown the garbage collector has run. If you get these exceptions then you still have references to the memory.
Reality : Hmmm. I know this is in the spec, but I am not convinced that it works perfectly. Our application was load tested recently and suffered from this exception. I added a piece of code that calls system.gc() if the free/avail memory < 20%. This code is run at the end of each users call to our jspService in our main jsp. We ran the load test again and did not get the exception. *No* other changes were made. Timeout was not reduced, *nothing*, repeat *nothing* else was changed. My conclusion was that the gc needs a small amount of memory *in* the *sandbox* to run, so if you leave it too late (we were eating memory at a hell of a rate) it is not possible. I appreciate that this is not necessarily a correct conclusion!