Les différents objets sont stockés dans un espace que l’on appelle la heap. Cette zone est gérée par un composant particulier, le garbage collector. Il existe plusieurs garbage collectors dans la JVM qui répondent à des besoins différents. Je ne vais pas revenir sur la gestion de la mémoire que j’ai déjà abordée dans un article précédent mais je vais essayer d’expliquer dans cet article le fonctionnement d’un collector en particulier, le garbage first (G1), apparu en expérimental à partir de la version 1.6.14 et utilisable à partir de la Java 7 update 4 (ou Java >1.6.20 pour ceux qui sont toujours en Java 6).
Avant de commencer je vais faire une remarque que beaucoup devraient prendre en compte. Depuis la version 5 de Java, une nouvelle fonctionnalité est apparue au sein de la JVM, les ergonomics.... La JVM est ainsi capable de trouver elle même à son démarrage les meilleurs paramètres d’exécution : le bon garbage collector, les bons paramètres de JIT (compilateur Just In Time),....
Le tuning de la JVM est quelque chose qui se fait de plus en plus rarement et que pour des besoins spécifiques. Les problèmes de performance viennent essentiellement du code et non de la plateforme d’exécution. Je vous conseille de lire ce post du blog de la société Ippon sur le sujet.
Donc le garbage first...pourquoi un nouveau garbage ?
Les algorithmes de Garbage n’ont fait que s’améliorer depuis la mise en place de Java. Dans mon article sur la gestion de la mémoire en Java je parlais de l’algorithme le plus utilisé aujourd’hui, le Concurrent Mark Sweep Collector (CMS) et du découpage de la mémoire (la heap) en différente zone
Aujourd’hui les ressources machines et notamment la RAM et le nombre de processeurs ou de coeurs ne font qu’augmenter. Le garbage collector doit parcourir des zones toujours plus grandes lors de l’analyse des objets en mémoire. En fonction de la nature de votre application vous devrez choisir entre
- limiter les temps de pause liés au garbage collector lors d’une collect majeure (cas des applications avec IHM)
- consommer un minimum de mémoire (traitement batch)
Plusieurs paramètres permettent de jouer sur le dimensionnement de ces différentes zones.
- Pour la HEAP, plus la taille de la mémoire est grande, moins le garbage collector s’exécutera pour essayer de trouver de la place, mais plus les collectes majeurs seront pénalisantes
- Pour le sous découpage, plus la YOUNG SPACE sera grande plus les collectes mineures seront rares mais si la taille de la TENURED est sous dimensionnée plus la fréquence des collectes majeures augmentera.
Vous pouvez vite vous rendre compte que trouver le bon paramétrage n’est pas simple et c’est la raison pour laquelle les ingénieurs de Sun ont essayé de rendre la JVM intelligente pour s’auto ajuster.
Le Garbage First (G1) a été conçu pour remplacer à terme CMS, tout particulièrement pour les applications qui utilisent un grand espace mémoire et qui nécessitent une forte disponibilité sans avoir des baisses de performances lorsque le GC fonctionne.
Son approche est totalement différente de CMS et au lieu de découper la mémoire en 3 zones (young, tenured et perm generations), elle est découpée en un ensemble de petites zones de même taille. Chacune de ces zones est assignée au même rôle (eden, survivor, old).
Quand il est dans sa phase de collecte, G1 commence par effectuer une phase de marquage pour déterminer si les objets en mémoire sont utilisés ou non. Comme il a fait une passe complète il sait quelles sont les régions vides ou non (d’où le nom de Garbage First). Son activité de collecte et de compactage se concentrent sur les zones de la heap qui sont susceptibles d’être pleines d’objets à nettoyer.
Afin de ne pas ralentir l’application, l’utilisateur peut définir un objectif de pause maximal autorisé pour la collecte. G1 sélectionnera en fonction de cet objectif le nombre de zones qu’il analysera. Le nombre est déterminé en fonction des précédentes collectes et c’est pourquoi l’algorithme amène de la prédictibilité même si ce n’est pas d’une certitude absolue (90% des collectes respectent les objectifs fixés).
G1 copie les objets d’une ou plusieurs des zones identifiées vers une nouvelle zone de la heap. Les objets qui ne sont plus utilisés, sont libérés et ceux restant, sont compactés dans la nouvelle zone (réduction de la fragmentation).
Cette opération s’effectue en parallèle sur les différents processeurs disponibles afin de limiter les temps de pause et manipuler le plus d’objets possibles. Les collectes majeures (de toute la mémoire) sont toujours effectuées sur un seul thread.
Quand utiliser le Garbage First ?
Le G1 est particulièrement adapté pour les applications travaillant avec beaucoup de mémoire (>6Go) et nécessitant des temps de latence liés au GC (<0.5sec). Ces chiffres sont des chiffres théoriques donnés par Oracle.
Il est recommandé de passer au G1 si
Par contre si vous n’avez pas de souci vous n’avez aucune raison de changer, et laissez la JVM choisir l'algorithme qui lui parait le mieux.
Comment utiliser le Garbage First ?
Pour activer le G1 et personnaliser son exécution vous devez ajouter plusieurs paramètres lors du lancement de la JVM.
Voici la liste de ses paramètres
Afin de ne pas ralentir l’application, l’utilisateur peut définir un objectif de pause maximal autorisé pour la collecte. G1 sélectionnera en fonction de cet objectif le nombre de zones qu’il analysera. Le nombre est déterminé en fonction des précédentes collectes et c’est pourquoi l’algorithme amène de la prédictibilité même si ce n’est pas d’une certitude absolue (90% des collectes respectent les objectifs fixés).
G1 copie les objets d’une ou plusieurs des zones identifiées vers une nouvelle zone de la heap. Les objets qui ne sont plus utilisés, sont libérés et ceux restant, sont compactés dans la nouvelle zone (réduction de la fragmentation).
Cette opération s’effectue en parallèle sur les différents processeurs disponibles afin de limiter les temps de pause et manipuler le plus d’objets possibles. Les collectes majeures (de toute la mémoire) sont toujours effectuées sur un seul thread.
Quand utiliser le Garbage First ?
Le G1 est particulièrement adapté pour les applications travaillant avec beaucoup de mémoire (>6Go) et nécessitant des temps de latence liés au GC (<0.5sec). Ces chiffres sont des chiffres théoriques donnés par Oracle.
Il est recommandé de passer au G1 si
- les full GC sont trop fréquents
- les GC trop longs (>0,5 à 1sec)
- Le nombre d’objets alloués en mémoire fluctue beaucoup.
Par contre si vous n’avez pas de souci vous n’avez aucune raison de changer, et laissez la JVM choisir l'algorithme qui lui parait le mieux.
Comment utiliser le Garbage First ?
Pour activer le G1 et personnaliser son exécution vous devez ajouter plusieurs paramètres lors du lancement de la JVM.
Voici la liste de ses paramètres
Paramètre avec la valeur par défaut | Description |
-XX:+UseG1GC | Utilisation du Garbage First (G1) Collector |
-XX:MaxGCPauseMillis=200 | Défini un objectif de temps de pause maximal accordé au GC (en ms). |
-XX:InitiatingHeapOccupancyPercent=45 | Pourcentage d’occupation de la mémoire qui démarre un cycle de GC en mode concurrent (avec l’application). |
-XX:NewRatio=2 | Ratio entre les tailles des générations new/old. |
-XX:SurvivorRatio=8 | Ratio entre les tailles des zones eden/survivor |
-XX:MaxTenuringThreshold=15 | Seuil maximal de l’objet avant de passer dans la tenuring. |
-XX:ParallelGCThreads=n | Définit le nombre des threads qui seront utilisés pendant les phases de la collecte exécutées en parallèle. Le nombre par défaut dépend de la plateforme sur laquelle la JVM est exécutée. |
-XX:ConcGCThreads=n | Définit le nombre des threads qui seront utilisés pendant les phases de la collecte exécutées en mode concurrent. Le nombre par défaut dépend de la plateforme sur laquelle la JVM est exécutée. |
-XX:G1ReservePercent=10 | Définit le pourcentage de la heap qui est réservé au GC pour gérer les cas la heap est saturée. Cet espace évite de dégrader vraiment les perfs quand la mémoire est pleine |
-XX:G1HeapRegionSize=n | Avec le G1 la heap est divisée en des zones de taille uniforme. Vous pouvez personnaliser la taille de ces zones. La valeur par défaut dépend de la taille de heap. Ma valeur minimale sera de 1Mo et la max de 32. |
Aucun commentaire:
Enregistrer un commentaire
Remarque : Seul un membre de ce blog est autorisé à enregistrer un commentaire.