Did you check the growth in the number of threads? Are the threads growing exponentially? You might have to synchronize cleanup of related classes. You can also open the JMX management interface for your application and view all that is happening using VisualVM or JConsole. If everything is transactional and stateless as you say, there should be no reason for the old generation to grow up to the ceiling of the old generation space; most of the GC (minor) should occur in the young generation space of the heap. You can use commercial (or, open source) Java profiler tools to identify which methods have performance issues.