Try with this option:
+XX:+HeapDumpOnOutOfMemoryError -XX:+HeapDumpPath=dump.log
Also try with lower initial memory -Xms .
then you can check the dump to see if the object allocation was a problem.
When run try
jps
This will output all java processes, say Tomcat - PID 4444:
jmap -dump:format=b,file=heapdump 4444
and
jhat heapdump
If you run out of memory while running jhat, just add more memory. From there you can check a bunch of your application.
Another way is to enable Hibernate statistics to verify that you are not receiving more objects. Although it looks like a complete garbage collection, every hour should not be a problem (a room for this is better there).
-verbose:gc -Xloggc:/opt/tomcat/logs/gc.out -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
And with GCViewer, for example, look at each memory space (ternured, eden, survivors, perm).
Another handy tool:
jstack 4444 > stack.txt
This will allow you to get a full stack trace for each thread running inside the java process using pid 4444.
Keep in mind that you need privileges if you run Tomcat as root or another user.
jps
will not display a process that does not have rights, so you cannot connect to it.
Since I donβt know what your application is about (and therefore I donβt know its requirements), 3 million instances look like a lot.
With Hibernate statistics you can see which classes you create the most.
Then setting up your eden and ternured garbage eden and ternured can be more efficient.
New instances of objects are sent to eden. When it fills the meager gc triggers. What is not removed falls into the space of the survivor. When it fills, it goes into state. Full gc will occur when ternured is full.
In this picture (which is inaccurate), I left out the String , which became interned and memory-mapped files (which are not on the heap). See which classes you create the most. Intensive use of String can quickly fill perm.
I assume you are doing this, but use a managed factory session like Spring (if on your stack) and avoid manually managing transactions and sessions.
Keep in mind that objects are deleted in the GC if the object does not belong to it. As long as the object is available in your application, the object remains.
If your ServletContextListener instantiates the controllers and is stored in the getServletContext event. Make sure you completely delete the link after that, if you save the link, the objects will not be deleted, since they are still available.
If you manage your own transactions and session (this is normal if you cannot use the framework), you need to deal with code maintenance and errors that Spring-tx , for example, solved and improved.
I would personally use FOSS . But of course, sometimes you cannot expand the stack.
If you use Hibernate , I would look at Spring-orm and Spring-tx for transaction and session management. Also take a look at the Hibernate patter Open Session In View .