The best thing to do is add -XX:+HeapDumpOnOutOfMemoryError to the JAVA_OPTS in the run script. Then when you get the OOME, the JVM will dump the heap contents to a file. You can open the file using a tool such as VisualVM. That might tell you what is using up the heap.
You should also monitor GC statistics. You can usually tell, by monitoring the heap usage after a major collection, whether the app has a leak - the tend line will have a positive slope.
For suggestions on how to gather GC data and analyze it, see these white papers:
Java Garbage Collection Statistical Analysis 101
Java Garbage Collection Performance Analysis 201
at
http://www.cmg.org/cgi-bin/search.cgi?q=java+peter+johnson&x=30&y=10