La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Réglage des garbage collectors (GC) sur JDK1

Présentations similaires


Présentation au sujet: "Réglage des garbage collectors (GC) sur JDK1"— Transcription de la présentation:

1 Réglage des garbage collectors (GC) sur JDK1
Réglage des garbage collectors (GC) sur JDK1.6 Exemple de la plateforme d’échanges OSB/MOM A. Dewavrin - 3 Juin 2013 CTR

2 Historique des versions
Date Auteur Actions Version 03/06/2013 Anselme Dewavrin Récapitulatif du travail d’amélioration des GC de la plateforme d’échange V0.1 05/06/2013 Ajouts et conclusion V0.2 06/06/2013 Simplifications et schémas V0.3 CTR

3 Problématique Les JVMs* se figent régulièrement, tour-à-tour, typiquement pendant des durées de quelques secondes Conséquences : Ces pauses peuvent provoquer des timeouts sur les appelants (Tunnel de commande, Compiere, historisation) Suspicion de nombreux dysfonctionnements (abandon de transactions etc.) dans le MOM et l’OSB en prod. La moitié des trous dans l’historique Flowtracker est due à ces pauses. La cause : Un code Java ne relâche jamais la mémoire. C’est un mécanisme (garbage collector) qui fait régulièrement la récupération de la mémoire abandonnée, provoquant des pauses. *par exemple sur la plateforme d’échange, décrite en annexe

4 Anatomie de la mémoire d’une JVM
New (ou Young) Les objets sont créés en Eden Eden La zone « new » est balayée par un garbage-collector (minor) qui provoque normalement des pauses courtes… Les objets ayant survécu à un ou plusieurs passages du garbage collector de la zone « new » sont placés en Survivor, alternativement S1 et S2 S1 S2 Old (ou Tenured) …la zone « old » par un autre GC (major), le plus connu car son réglage par défaut provoque des pauses longues de la JVMs, parfois de plusieurs dizaines de secondes. On appelle cela « full garbage ». Les objets ayant survécu à de nombreux passages du garbage collector de la zone « new » sont placés en zone « old » (c’est ce qui est nommé « promotion ») Les objets et métadonnées (classes, etc.) éternels sont placés dans la zone « permanent » Perm xss xss xss Les données d’appel et retour de chaque thread sont stockées en zone « XSS »

5 Activité des garbage collectors
1. L’application demande régulièrement de la mémoire mais ne la libère jamais (principe de java). La mémoire est réservée en zone « new » (précisément, en Eden) 2. Quand la new est pleine, un garbage de zone « new » est déclenché. 3. Dans le cas idéal tous les objets sont désormais inutilisés et la mémoire est récupérée 4. Quand l’application est plus chargée, la new se remplit plus vite et les garbages new sont plus fréquents 5. Quand il reste des objets encore utilisés, le garbage ne peut pas récupérer leur mémoire, il les laisse en new mais les déplace dans une des zones « survivor » 6. Quand des objets ont survécu à plusieurs garbages, ils sont considérés comme durables, et sont promus en zone « Old » ce qui leur évite d’être scannés tout le temps pour rien par le garbage de zone « new ». 7. Quand la zone « old » est remplie, un garbage « full » se déclenche et récupère la mémoire des objets inutilisés. Par défaut cela provoque une pause (nommée « stop-the-world ») 8. Le niveau atteint après un garbage full donne une idée de la mémoire minimum nécessaire à l’application. Il ne reste que les objets très durables. Si trop peu de mémoire est récupérée on a un out-of-memory de type « java heap». Si la JVM passe plus de 99% de son temps à faire du garbage on a un out-of-memory de type  «GC overhead limit » 2 1 4 New 5 3 6 7 Old 8

6 Logs de l’activité des garbage collectors
Il est possible (souhaitable) de demander au garbage de logger son activité. Voici ce qu’on y voit : {Heap before GC invocations=7791 (full 39): par new generation total K, used K [0x , 0x , 0x ) eden space K, 100% used [0x , 0x , 0x ) from space K, 61% used [0x c400000, 0x , 0x ) to space K, 0% used [0x , 0x , 0x c400000) concurrent mark-sweep generation total K, used K [0x , 0x d , 0x d ) concurrent-mark-sweep perm gen total K, used K [0x d , 0x , 0x ) : [GC : [ParNew Desired survivor size bytes, new threshold 15 (max 15) - age 1: bytes, total - age 2: bytes, total - age 3: bytes, total - age 4: bytes, total - age 5: bytes, total - age 6: bytes, total - age 7: bytes, total - age 8: bytes, total - age 9: bytes, total - age 10: bytes, total - age 11: bytes, total - age 12: bytes, total - age 13: bytes, total - age 14: bytes, total - age 15: bytes, total : K->61866K(917504K), secs] K-> K( K), secs] [Times: user=0.55 sys=0.01, real=0.20 secs] Heap after GC invocations=7792 (full 39): par new generation total K, used 61866K [0x , 0x , 0x ) eden space K, 0% used [0x , 0x , 0x ) from space K, 47% used [0x , 0x a930, 0x c400000) to space K, 0% used [0x c400000, 0x c400000, 0x ) concurrent mark-sweep generation total K, used K [0x , 0x d , 0x d ) } Le remplissage des zones survivor est indiqué en tant que « from » et « to » L’âge maximum avant de passer en zone « old » Les objets du survivor, ayant survécu à 1 ou plusieurs garbages de la zone « new », peuvent être indiqués sur demande dans le log gc (paramètre printTenuringDistribution). Ici, après 15 ils seront déplacés en zone « old ». C’est la « promotion ». La durée de la pause causée par le GC

7 Démographie et réglages de la zone « survivor »
Eden Eden Eden Age 1 Age 2 Age 3 Age 4 Age 5 Age 6 Age 7 Age 8 Age 9 Age 10 Age 15 Le process de maturation (tenuring) est trop court. Trop d’objets sont copiés en old alors qu’ils vont mourir peu après. Cela provoque un remplissage inutile de la old et des garbages plus fréquents, et donc plus de pauses. Paramètre : SurvivorRatio L’âge maxi en survivor est trop grand, on pourrait promouvoir plus vite les objets en old pour leur éviter d’être scannés de nombreuses fois pour rien par le garbage collector de la zone « New ». A gauche, le cas d’une charge régulière, à droite une charge par à-coups Paramètre : MaxTenuringThreshold Situation idéale : à la fin de la maturation, il reste en survivor uniquement les objets durables. Seuls ceux-là seront promus en old. Old Old Old

8 Réglages de la zone « new »
Eden Eden Age 1 Age 2 Age 3 Age 4 Age 5 Age 6 Age 7 Age 8 Age 9 Age 10 Age 15 Situation idéale Le Eden est trop court. En l’agrandissant un peu on y aurait laissé mourir les objets les plus éphémères, évitant une copie pour rien d’un grand nombre d’objets dans les premiers âges des survivors Paramètre : NewRatio ou NewSize Old Old

9 Proportions de la mémoire d’une JVM
New (ou Young) NewRatio Rapport entre Old et New. Typiquement 2 Eden S1 S2 Xmx (le « heap ») Typiquement 2G SurvivorRatio Rapport entre Eden et un Survivor. Typiquement 6 car on observe qu’un objet sur 6 n’est pas éphémère Old (ou Tenured) PermSize Typiquement 0.5 à 1 G Suivant la complexité de l’application (nb de classes) Perm xss xss xss Xss Taille de la stack d’une thread. Laisser par défaut sauf si erreurs « stack overflow »

10 Pauses d’une application java
Une application Java fait des pauses, c’est un fait. Pour les minimiser il faut éviter les promotions inutiles vers la zone « Old ». Et quand c’est impossible, on abandonnera le garbage collector de zone « Old »par défaut pour utiliser au choix CMS ou parallèle. Type de GC Old avantages Inconvénients Par défaut Efficacité CPU et RAM. Conçu pour les machines monoprocesseur. Pauses longues CMS Pauses très réduites Fragmentation de la mémoire java Parallèle Pauses réduites inefficacité CPU. La parallélisation sur 4 procs n’apporte qu’une réduction par 2 des pauses Choisi

11 Détection des pauses d’une application java
Quand on suspecte une application de faire des pauses longues dues à sa gestion de mémoire (temps de réponses de temps en temps beaucoup plus grands, attente hors charge avec un cpu à 100%), on activera le log de l’activité du garbage collector avec les paramètres de lancement suivants : -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:chemin/gc.log Ensuite après de l’activité, on pourra rechercher dans le fichier le mot « real » avec par exemple la commande : grep real gc.log Pauses du GC de zone « New » : : K->92106K(917504K), secs] K-> K( K), secs] [Times: user=0.62 sys=0.00, real=0.22 secs] Pauses du GC de zone « Old » (full GC): : [Full GC [PSYoungGen: 10981K->0K(950016K)] [PSOldGen: K->967902K( K)] K->967902K( K) [PSPermGen: K->266201K(716800K)], secs] [Times: user=4.59 sys=0.01, real=4.60 secs]

12 Diminution des pauses d’une JVM
Zone « new » : La parallélisation est possible sur les machines multicoeurs. Il y a toujours des pauses, mais plus courtes. Réglage par défaut Réglage parallèle. Paramètres : «  UseParNewGC  » «  ParallelGCThreads =4 » New 1 2 pause 0.4s pause 0.1s Zone « old » : L’utilisation d’un algorithme concurrent (qui se déroule en grande partie en même temps que l’application), permet de limiter les « stop-the-world » 3. Réglage par défaut 4. Réglage CMS. Paramètres : «  UseConcMarkSweepGC  » 4 3 Old pause 0.5s (remark) pause 1s (initial mark) pause 8s

13 Mesure de la réduction des pauses
Après changement des réglages, on relancera les mesures. Zone « New » : grep real gc.log : K->90921K(917504K), secs] K->90921K( K), secs] [Times: user=0.51 sys=0.05, real=0.15 secs] Zone « Old » Comme on a mis en place le CMS, il faut uniquement prendre en compte les phases « initial mark » et « remark », les seules qui gèlent la JVM. On voit que les pauses ont été raccourcies grep remark\|initial gc.log : [GC [1 CMS-initial-mark: K( K)] K( K), secs] [Times: user=0.29 sys=0.01, real=0.30 secs] : [GC[YG occupancy: K ( K)] : [Rescan (parallel) , secs] : [weak refs processing, secs] [1 CMS-remark: K( K)] K( K), secs] [Times: user=1.34 sys=0.01, real=0.51 secs]

14 Causes d’échec du CMS Deux cas peuvent provoquer un échec du CMS, ce qui n’est pas grave mais conduit à un GC classique, et donc une pause longue. Type d’échec Cause schéma détection Comment éviter Fragmentation de la zone « Old » Promotion impossible de la New vers la Old. En effet le CMS ne défragmente pas la mémoire, formant un gruyère avec des trous de plus en plus petits. Les gros objets ne peuvent plus être promus grep fail gc.log : [GC : [ParNew (promotion failed) En dev : on évitera de manipuler de gros objets longtemps. En prod : on mettra plus de Old Urgence Une accélération de l’activité rend improbable de finir à temps le garbage full en mode concurrent. Le CMS compare de temps qu’il lui faudra au temps qu’il reste avant que la zone « Old » ne soit pleine. Il peut alors décider de faire un GC classique dans le but de geler la JVM, arrêtant ainsi le remplissage. (concurrent mode failure): K-> K( K), secs] K-> K( K), [CMS Perm : K->275121K(716800K)], secs] [Times: user=14.61 sys=0.11, real=16.85 secs] En dev : on évitera les gros objets En prod On évitera les promotions inutiles (réglage eden et survivors) on déclenchera plus tôt le CMS au moyen du paramètre CMSInitiatingOccupancyFraction (80% à 92% par défaut). ! ?

15 Dimensionnement RAM des machines
Méthode théorique Il faut calculer : heap + perm + nb_threads * profondeur d’appels + empreinte fichiers ouverts Et ajouter l’OS, les autres applications (easytrust, omnivision, tivoli, etc.), des caches et buffers disque. Méthode itérative: 1. On choisi une des configurations typiques : 2. On ajuste la mémoire heap des JVMS en fonction du niveau bas du Old (après un GC full). On règle le « Old » à deux ou trois fois le niveau bas. 3. On surveille le swapping au moyen des colonnes « si » et « so » de vmstat (et non pas sur la commande free comme le fait Tivoli actuellement). Si ça swappe il faut ajouter de la RAM ou diminuer les JVMs (swapper est plus grave que garbager souvent). /

16 Conclusions 1. Malheureusement il n’existe pas de réglage universel car chaque application est différente en termes : d’utilisation de la mémoire (nombre et longévité des objets utilisés) d’attendus (latence acceptée, temps de calcul maximum) d’infrastructure utilisée (mémoire disponible de la machine, nombre de cpus…) 2. Pour le GC « major », c’est-à-dire de la zone « old », il faut accepter un défaut, au choix: forte utilisation du cpu (GC parallèle) longues pauses (GC classique) fragmentation de la mémoire nécessitant un petit surdimensionnement (GC CMS) 3. Le réglage suivant choisi pour la plateforme d’échange a divisé les pauses par 10 au moins : GC minor en parallèle, GC major en CMS heap de 2Go, new de 1/3, survivors de 1/6 Seul l’OSB a pour l’instant été laissé à 3Go suite à un incident. On a encore des pauses de temps en temps, dues à la fragmentation (20 fois moins). 4. Des bonnes pratiques de développement (attention aux instanciations inutiles ou implicites) peuvent être promues, mais dans le cas de progiciels c’est parfois difficile à imposer. Il ne reste alors que le tuning technique pour faire fonctionner l’appli. 5. Le futur algorithme de garbage (G1) est prometteur, il faudra l’évaluer avec java 7.

17 Annexe : Plateforme d’échanges (production)
Une cinquantaine de JVMs en weblogic / Basées sur le jdk 1.6 de Sun

18 Sources /


Télécharger ppt "Réglage des garbage collectors (GC) sur JDK1"

Présentations similaires


Annonces Google