I have a Java app which shows different GC behaviors in different environments. In one environment, the heap usage graph is a slow sawtooth with major GCs every 10 hours or so, only when the heap is >90% full. In another environment, the JVM does major GCs every hour on the dot (the heap is normally between 10% and 30% at these times).

My question is, what are the factors which cause the JVM to decide to do a major GC?

Obviously it collects when the heap is nearly full, but there is some other cause at play which I am guessing is related to an hourly scheduled task within my app (although there is no spike in memory usage at this time).

I assume GC behaviour depends heavily on the JVM; I am using:

* Java HotSpot(TM) 64-Bit Server VM 1.7.0\_21 Oracle Corporation
* No specific GC options, so using the default settings for 64-bit server (PS MarkSweep and PS Scavenge)

Other info:

* This is a web app running in Tomcat 6.
* Perm gen hovers around 10% in both environments.
* The environment with the sawtooth behaviour has 7Gb max heap, the other has 14Gb.

Please, no guesswork. The JVM must have rules for deciding when to perform a major GC, and these rules must be encoded deep in the source somewhere. If anyone knows what they are, or where they are documented, please share!