The literal cause of an Out Of Memory Error is simple: a given Tomcat instance uses up all of the heap memory allocated to it, causing an application or server crash.
Thus, the errors themselves are not particularly puzzling. The reason why OOMEs have become such a persistent topic of discussion in the Apache Tomcat community is that they are difficult to trace to their root cause.
A stack trace will not show the cause, as the problem usually lies not with Tomcat, but the web application.
Meanwhile, the 'incorrect' web app code causing Tomcat to run out of memory is usually technically correct. That is to say, in any context other than a container managed environment, the code would be considered standard. It is easy to see why a developer might have trouble determining which 'correct' section of their code was incorrect.
Here are some of the most common root causes of an OOME:
- a simple case of the heap size being too small
- running out of file descriptors
- more open threads than the host OS allows
- code with high amounts of recursion
- code that loads a very large file into memory
- code that retaining references to objects or classloaders
- a large number of web apps and a small PermGen