4. Qu’est ce & Où c’est stocké
class MaClasse {
private int iPrimitif = 0;
private Integer iObject;
public MaClasse() {
int a = iPrimitf + 1;
iObject = a;
}
}
● 4 choses dont 1 piège
● a dans la stack (pile)
● iPrimitif & iObject dans la heap (tas)
● la structure de la classe dans la heap
(avant le java 8 dans la PermGen
Space)
5. Aparté : La off-heap
● Stockage de données dans la mémoire mais en dehors de la heap
● Données qui ne sont pas soumis aux GC:
○ très intéressant pour les données référentiels ou cache => gain de performance
● Comment ? avec la classe Unsafe (/! changement en JDK 9)
○ Accès direct à la mémoire avec des malloc et des free ...
6. Rappel pour cette présentation
● On va donc s’intéresser à la heap
● Dans cette présentation, on va parler de la JVM Oracle mais il en existe
d’autres :
○ Zing (de Microsoft Azul) payante promet peu de pic de latence, pas de “stop the world”
○ JRockit dans un autre temps (IBM)
○ et bien d’autres
10. Vocabulaire
● Minor GC : nettoyage de la young
● Major GC : nettoyage de la tenured
● Full GC : nettoyage de toute la heap
● Pause GC : temps d’arrêt de fonctionnement de la JVM pendant la libération
mémoire
○ => attention au “stop the world” (STW)
11. Serial GC (1/3)
● Utilise un algorithme mark-copy pour la Young Generation
● Utilise un algorithme mark-sweep-compact pour la Old Generation
● Pas de parallélisation des tâches du GC (pas de support des multi-coeurs)
● Phénomène stop the world durant le Full GC
Cette stratégie de GC est obsolète
12. Serial GC (2/3) - Minor GC, mark and copy
● Parcours des objets en Eden & S1
● Suppression des objets qui ne sont plus référencés
● Marquage des objets qui vont survivre
● Copie de ces objets dans la zone destination (S2, ou OLD si il change de
génération)
Prochain GC S1 devient S2
13. Serial GC (3/3), Full GC - mark sweep compact
● Déclencher parce qu’il n’y pas plus de place dans la Young Generation
● Ressemble au mark sweep mais résout les problèmes de fragmentations
15. Parallel GC
● Idem que le Serial GC sauf que le Full GC est effectué par plusieurs threads
(en parallèle)
● Permet de réduire les préjudices du Stop The World
Cette stratégie est par défaut dans Java 8
16. CMS GC
● Permet d’éviter de long temps de pause et donc de réduire les
conséquences des phénomènes de STW
● Par rapport aux 2 autres algo, cette implémentation a l’énorme avantage de
scaler (quand on augmente la taille de la heap). On peut allègrement
augmenter la taille mémoire (à plusieurs dizaines de Gigas) sans avoir des
temps de pause GC rédhibitoire.
17. Quelques commandes
jmap -heap <pid> : pour avoir les informations de la heap (et le GC utilisés)
-XX:+UseSerialGC : pour utiliser le Serial GC
-XX:+UseParallelGC : pour utiliser le Parallel GC
-XX:+UseConcMarkSweepGC : pour utiliser le CMS GC
-XX:+UseG1GC : pour utiliser le G1 GC
21. Nouvelles organisations mémoire
● La mémoire n’est plus découper en Eden, Young et Old
● La mémoire est découpée en région, ces régions ont une responsabilité
Young ou Old
● La heap est découpé (approximativement) en 2000 régions
● Une région peut faire entre 1Mo ou 32Mo
● Une région peut être libre et donc pas concerné par le GC
22. Nouvelles organisations mémoire
● Une région libre peut prendre une responsabilité de Young ou Old
● Une région qui a un responsabilité Young ou Old peut redevenir libre
● Le changement de responsabilités d’une région permet un
dimensionnement dynamique de la Young et Old (adapté à l’utilisation)
● Le principe du G1 consiste à récupérer autant que possible des régions par
GC, en nettoyant des régions qui n’ont que des données à effacer
29. NB pour les 2 slides suivants
● Il existe plusieurs problèmes avec des sources bien différentes
● On parle de quelques exemples significatifs, il en existe de nombreux autres
○ ie on ne donne que quelques pistes ou idées brèves
● Il existe de très nombreux paramètres JVM pour la configuration du GC
30. Problème de sizing (naïf)
● Plusieurs possibilités :
○ Trop d’objets alloués => debugger pour optimiser l’allocation mémoire
○ La taille de la heap est trop petite => modifier la taille de la heap avec le paramètre -Xmx
○ La taille de la Young est trop petite => on observe un phénomène de “prematurate
promotion” => modifier la taille de la Young avec -Xmn
31. Problème de débit ou de pause
● Plusieurs possibilités :
○ Trop d’objets dans la Old => vérifier que l’on a pas le problème de “prematurate promotion”
○ Trop de données en cache => utiliser de la off-heap
○ Augmenter la taille de la Heap pour ne plus avoir de Full GC
○ Temps de pause GC important => quels algos GC vos utilisez passez au CMS ou G1 si c’est
plus adapté à votre cas d’utilisation
Les objets récents sont supprimés ou copié vers une autres regions. Certains objets récents peuvent être promu dans la old.
Il y a STW. Eden size et Young sont calculé au prochain GC.
Young GC est exécuté en //
Initial Mark des objets récents (young)
Concurrent Marking, si une region est vide (X) est immédiatement détruite. MAJ de l’increment de vie des objets
Les régions vides sont supprimées et récupérées.
MAJ des niveaux de vie des regions
La Young et la OLD peuvent être rassemblés en même temps (suivant leur niveau d’activité)
Compact (vert foncé et bleu foncé)
Summary of Old Generation GC
In summary, there are a few key points we can make about the G1 garbage collection on the old generation.
Concurrent Marking Phase
Liveness information is calculated concurrently while the application is running.
This liveness information identifies which regions will be best to reclaim during an evacuation pause.
There is no sweeping phase like in CMS.
Remark Phase
Uses the Snapshot-at-the-Beginning (SATB) algorithm which is much faster then what was used with CMS.
Completely empty regions are reclaimed.
Copying/Cleanup Phase
Young generation and old generation are reclaimed at the same time.
Old generation regions are selected based on their liveness.