Pourquoi les temps de GC augmentent-ils régulièrement sur une application Java longue durée à volume élevé?


J'ai une application Java à volume élevé qui gère une charge cohérente de 50000msgs / sec. Il est réglé pour un débit élevé en utilisant les paramètres suivants:

-Xmx3g -Xms3g -XX:NewSize=2g -Xss128k -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=90 -XX:+UseParallelGC -XX:ParallelGCThreads=12 -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError

Je constate que les jeunes temps de GC grimpent régulièrement de 50ms quand il commence à 200ms à la fin de la journée, bien que le la fréquence des exécutions GC reste la même.

Si j'essaie la même exécution en utilisant le collecteur ParNewGC, les temps de GC augmentent à un rythme beaucoup plus rapide. Quelqu'un a-t-il des idées sur ce problème?

Author: JoseK, 2010-09-09

2 answers

Si vous avez une fuite de mémoire, ou un cache en mémoire qui utilise progressivement de plus en plus de mémoire, cela aurait pour effet d'amener le GC à faire plus de travail en traçant les objets accessibles.

, d'Autres possibilités sont:

  • Vous avez une fuite de mémoire non-tas, ce qui entraîne une augmentation de la pagination; c'est-à-dire la copie de pages de mémoire physique sur le disque et à l'arrière.

  • Certains processus externes consomment des quantités croissantes de mémoire, ce qui entraîne une augmentation la pagination.

  • La nature des objets générés dans la jeune génération change au fil du temps, de sorte que plus de travail est nécessaire pour tracer les objets accessibles. Il se peut simplement qu'une plus grande proportion d'entre eux survivent après la première collection.

 3
Author: Stephen C, 2013-04-20 03:27:06

Il peut s'agir d'une combinaison de plusieurs facteurs:

  • Une vraie fuite de mémoire. (Les objets sont toujours référencés par accident)
  • Plus d'objets, ou peut-être une distribution différente des objets entre les gc-pools.
  • Le tas est plus grand. Tracez le temps gc et la taille du tas.
  • Fragmentation de la mémoire. Au niveau du système d'exploitation et/ou du tas java, en fonction de la jvm.

Pourquoi ne tracez-vous pas le nombre d'objets, la taille du tas et le temps de gc. (à l'aide d'un outil, ou par quering MBeans) Un tracé devrait vous indiquer la tendance; croissant, décroissant ou linéaire, et vous aidera à déterminer s'il y a une fuite. Si possible, videz également certaines statistiques de votre programme, comme le nombre de messages traités ou de sessions actives, etc.

Est-ce un vrai problème puisque vos messages ne sont pas traités pendant le gc?. Essayez la marque simultanée et balayez gc...

* -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
 2
Author: KarlP, 2010-09-09 10:57:26