O que faz com que a JVM faça uma grande coleta de lixo?

Eu tenho um aplicativo Java que mostra diferentes comportamentos de GC em diferentes ambientes. Em um ambiente, o gráfico de uso do heap é um dente de serra lento com os principais GCs a cada 10 horas, aproximadamente, apenas quando o heap está> 90% cheio. Em outro ambiente, a JVM realiza GCs importantes a cada hora no ponto (o heap normalmente fica entre 10% e 30% no momento).

Minha pergunta é: quais são os fatores que levam a JVM a decidir fazer um GC importante?

Obviamente, ele é coletado quando o heap está quase cheio, mas acho que há outra causa em jogo relacionada a uma tarefa agendada de hora em hora no meu aplicativo (embora não haja um aumento no uso de memória no momento).

Presumo que o comportamento do GC dependa fortemente da JVM; Estou usando:

VM do servidor Java HotSpot (TM) de 64 bits 1.7.0_21 Oracle CorporationNão há opções específicas de GC; portanto, use as configurações padrão do servidor de 64 bits (PS MarkSweep e PS Scavenge)

Outras informações:

Este é um aplicativo da Web em execução no Tomcat 6.Perm gen gira em torno de 10% em ambos os ambientes.O ambiente com o comportamento dente de serra tem 7 Gb de pilha máxima, o outro tem 14 Gb.

Por favor, sem adivinhações. A JVM deve ter regras para decidir quando executar um GC principal e essas regras devem ser codificadas profundamente na fonte em algum lugar. Se alguém souber o que são ou onde estão documentados, compartilhe!