Full GC deviennent très fréquentes

J'ai un Java webapp en cours d'exécution sur une instance de tomcat. Pendant les périodes de pointe de la webapp sert environ 30 pages par seconde et normalement de l'ordre de 15.

Mon environnement est:

O/S: SUSE Linux Enterprise Server 10 (x86_64)
RAM: 16GB

server: Tomcat 6.0.20
JVM: Java HotSpot(TM) 64-Bit Server VM 1.6.0_14
JVM options:
CATALINA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m
               -XX:+UseParallelGC
               -Djava.awt.headless=true
               -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
JAVA_OPTS="-server"

Après une couple de jours de disponibilité de la Pleine GC commence à se produire plus fréquemment et il devient un sérieux problème pour l'application de la disponibilité. Après un tomcat redémarrer le problème disparaît, mais, bien sûr, est de retour après 5 à 10 ou de 30 jours (non conformes).

La Pleine GC journal avant et après un redémarrage est à http://pastebin.com/raw.php?i=4NtkNXmi

Il montre un journal avant de le redémarrer à 6,6 jours de disponibilité où l'application a été la souffrance, car la Pleine GC nécessaire de 2,5 secondes et qui se passe tous les ~6 secondes.

Puis il montre un journal, juste après le redémarrage, où tous les GC n'est arrivé à toutes les 5-10 minutes.

J'en ai deux décharges à l'aide de jmap -dump:format=b,file=dump.hprof PID lorsque la totalité du GCs où les cours (je ne suis pas sûr de savoir si j'ai raison lorsqu'un Full GC était en cours ou entre les 2 Cg) et les ouvrit en http://www.eclipse.org/mat/ mais ne pas obtenir quelque chose d'utile dans la Fuite des Suspects:

  • 60MO: 1 exemple de "org.mise en veille prolongée.impl.SessionFactoryImpl" (j'utilise hibernate avec ehcache)
  • 80MB: 1 024 en cas de "org.apache.tomcat.util.les threads.ThreadWithAttributes" (ce sont probablement les 1024 travailleurs de tomcat)
  • 45 MO: 37 instances de "net.sf.ehcache.magasin.composé.impl.MemoryOnlyStore" (ce doit être mon ~37 cache régions ehcache)

Noter que je n'ai jamais eu un OutOfMemoryError.

Toutes les idées sur où dois-je chercher la prochaine?

Si vous avez 16 go de RAM sur le serveur, pourquoi ne pas utiliser un plus grand max de la taille du segment (-Xmx)?
Je n'ai jamais eu un OutOfMemoryError j'ai donc pensé que, puisque l'application peut s'exécuter alors c'est ok. Aussi, j'ai lu que le fait de donner trop de mémoire de la JVM va faire le Plein GC plus lent. Est-ce vrai?
Pouvez-vous reproduire le comportement dans un environnement de test? Peut-être avec certains tests de charge. J'ai débogué comportement comme ça avant, mais généralement avec BEAUCOUP de l'aide d'un profileur (qui va tuer votre serveur en production env).
aussi @cherouvim avez-vous vu oracle.com/technetwork/java/javase/gc-tuning-6-140523.html ? pourrait être utile.
"Je n'ai jamais eu un OutOfMemoryError" - pas tous la mémoire est utilisée, mais le GC se produisent parce que l'ancienne génération est pleine. Allouer plus de mémoire sera de garder des objets dans le jeune gen pour plus plus susceptibles d'obtenir nettoyé par un mineur collection / moins de chances de promotion.

OriginalL'auteur cherouvim | 2011-10-27