Eliot blogged about getting OutOfMemory errors after some days of running a web application.
This happened to me too and I spent almost a week trying to track down the leak with a whole arsenal of tools ... and it turned out there was no leak.
Most JVMs allocate memory on the heap for almost everything, except for reflective data. That is put in a separate location which is a section of the heap that is reserved for permanent generation. This gets easily filled up when you dynamically load an unload classes, or have a large number of classes. I simply added the following options to the java executable and all my worries were gone:
-XX:PermSize=256M -XX:MaxPermSize=256M
My entire command for Sun's JVM looks like this now:
java -server -Djava.awt.headless=true -Xms1024M -Xmx1024M
-XX:PermSize=256M -XX:MaxPermSize=256M
Hope this helps someone.