Récupération de la mémoire Java 7 (JDK 7) et documentation sur G1

Java 7 est sorti depuis un certain temps, mais je ne trouve aucune ressource valable sur la configuration des ramassemiettes , en particulier sur le nouveau collecteur G1 .

Mes questions:

  1. Est-ce que G1 est le collecteur par défaut de Java 7 et si non, comment puis-je activer G1?
  2. Quels parameters optionnels g1 possède-t-il dans Java7?
  3. Des modifications ont-elles été apscopes à d’autres collectionneurs tels que cms ou le collecteur parallèle de Java 7?
  4. Où puis-je trouver une bonne documentation sur la récupération de place dans Java 7?

Le ramasse-miettes G1 n’est pas la version par défaut de mon installation de Java, version 1.7.0_01. Vous pouvez voir par vous-même en utilisant des options de ligne de commande supplémentaires:

> java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -version -XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:ParallelGCThreads=4 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC java version "1.7.0_01" Java(TM) SE Runtime Environment (build 1.7.0_01-b08) Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode) Heap PSYoungGen total 37696K, used 1293K [0x00000007d5eb0000, 0x00000007d88c0000, 0x0000000800000000) eden space 32320K, 4% used [0x00000007d5eb0000,0x00000007d5ff3408,0x00000007d7e40000) from space 5376K, 0% used [0x00000007d8380000,0x00000007d8380000,0x00000007d88c0000) to space 5376K, 0% used [0x00000007d7e40000,0x00000007d7e40000,0x00000007d8380000) PSOldGen total 86144K, used 0K [0x0000000781c00000, 0x0000000787020000, 0x00000007d5eb0000) object space 86144K, 0% used [0x0000000781c00000,0x0000000781c00000,0x0000000787020000) PSPermGen total 21248K, used 2032K [0x000000077ca00000, 0x000000077dec0000, 0x0000000781c00000) object space 21248K, 9% used [0x000000077ca00000,0x000000077cbfc288,0x000000077dec0000) 

Vous n’avez pas besoin d’activer les options expérimentales pour activer le collecteur G1, mais:

 > java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseG1GC -version -XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation java version "1.7.0_01" Java(TM) SE Runtime Environment (build 1.7.0_01-b08) Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode) Heap garbage-first heap total 130048K, used 0K [0x000000077ca00000, 0x0000000784900000, 0x00000007fae00000) region size 1024K, 1 young (1024K), 0 survivors (0K) compacting perm gen total 20480K, used 2032K [0x00000007fae00000, 0x00000007fc200000, 0x0000000800000000) the space 20480K, 9% used [0x00000007fae00000, 0x00000007faffc288, 0x00000007faffc400, 0x00000007fc200000) No shared spaces configured. 

Je ne sais pas où vous pouvez trouver une bonne documentation.

Oracle a finalement rendu le G1 officiel dans Java 7 U4: http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html

Description: http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html

Options de ligne de commande: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#G1Options

Cependant, je ne pense pas que ce soit le collecteur par défaut de Java 7. Pour les serveurs, le collecteur par défaut est le Java 6.

Oui, G1 est le nouveau garbage collector standard dans Java 1.7 JVM.

Vous trouverez ici de nombreuses informations sur la manière d’utiliser et de configurer le nouveau ramasse-miettes:

L’utilisation de G1 G1 est toujours considérée comme expérimentale et peut être activée avec les deux parameters suivants:

-XX: + UnlockExperimentalVMOptions -XX: + UseG1GC

Pour définir un objective de temps de pause GC, utilisez le paramètre suivant:

-XX: MaxGCPauseMillis = 50 (pour une cible de temps de pause de 50 ms)

Avec G1, un intervalle de temps peut être spécifié pendant lequel une pause GC ne doit pas durer plus longtemps que le temps indiqué ci-dessus:

-XX: GCPauseIntervalMillis = 200 (pour une cible d’intervalle de pause de 200 ms)

Notez que les deux options ci-dessus représentent des objectives, pas des promesses ou des garanties. Ils pourraient bien fonctionner dans certaines situations, mais pas dans d’autres, et le GC pourrait ne pas toujours être en mesure de leur obéir.

Alternativement, la taille de la jeune génération peut être spécifiée explicitement pour avoir un impact sur les temps de pause d’évacuation:

-XX: + G1YoungGenSize = 512m (pour une jeune génération de 512 Mo)

G1 utilise également l’équivalent des espaces de survie, qui sont naturellement un ensemble de régions (potentiellement non contiguës). Leur taille peut être spécifiée avec les parameters habituels (par exemple, -XX: SurvivorRatio = 6).

Enfin, pour exécuter G1 à son plein potentiel, essayez de définir ces deux parameters qui sont actuellement désactivés par défaut car ils peuvent révéler une situation de concurrence rare:

-XX: + G1ParallelRSetUpdatingEnabled -XX: + G1ParallelRSetScanningEnabled

Une autre chose à noter est que G1 est très verbeux comparé aux autres GC HotSpot lorsque -XX: + PrintGCDetails est défini. En effet, il imprime des timings par thread-GC et d’autres informations très utiles pour le profilage et le dépannage. Si vous voulez un journal GC plus concis, veuillez utiliser -verbosegc (bien qu’il soit recommandé d’obtenir le journal GC plus détaillé).

J’ai également trouvé cet article très utile pour comprendre les parties internes de G1.

Encore plus d’infos ici .

1. G1 est-il le collecteur par défaut dans Java 7 (…)

La règle sur cette page Java 5 est toujours applicable dans Java 7 (et AFAIK, Java 8):

Sur les machines de type serveur exécutant la machine virtuelle du serveur, le récupérateur de mémoire (GC) est passé du collecteur série précédent (-XX: + UseSerialGC) à un collecteur parallèle (-XX: + UseParallelGC).

Mais considérez aussi:

  • Les -client virtuelles -client 64 bits ne sont pas -client avec une -client virtuelle -client , elles sont donc toujours une “classe serveur”
  • Depuis Java 7, utiliser -XX: + UseParallelGC (défini ou implicite) implique en outre -XX: + UseParallelOldGC (sauf s’il est explicitement désactivé)

Par exemple, sur Windows x64, vous exécutez …

  • Java 7 64 bits, vous obtenez par défaut le GC parallèle (pour les jeunes et les anciennes générations).
  • Java 8 32 bits, vous obtenez par défaut Serial GC (pour les deux générations)

1. (…) comment activer G1?

À partir de Java 7, simplement -XX:+UseG1GC . Peut-être est-il également intéressant de savoir quand vous souhaitez:

Les applications exécutées aujourd’hui avec le CMS ou le récupérateur de place ParallelOld bénéficieraient du passage à G1 si l’application possède un ou plusieurs des traits suivants.

  • Plus de 50% du tas Java est occupé par des données en direct.
  • Le taux de taux d’atsortingbution ou de promotion des objects varie considérablement.
  • Pauses de récupération de mémoire ou de compactage longues non souhaitées (plus de 0,5 à 1 seconde)

2. Quels parameters optionnels g1 possède-t-il dans Java7?

Je n’ai pas utilisé G1 moi-même, mais je suppose qu’il adhère aux mêmes indicateurs de base “débit / ergonomie” utilisés pour accorder les autres collecteurs parallèles. Dans mon expérience avec le GC parallèle, -XX:GCTimeRatio a été le pivot dans la fourniture du compromis vitesse-mémoire attendu. YMMV.

Les options spécifiques à G1 sont listées ici

3. Y a-t-il eu des changements dans (…) cms ou le collecteur parallèle dans Java 7?

Je ne sais pas, mais …

G1 est prévu comme remplacement à long terme du collecteur de marquage par balayage simultané (CMS)

4. Où puis-je trouver une bonne documentation sur la récupération de place dans Java 7?

Cela peut être pénible à trouver, n’est-ce pas? Probablement la meilleure page “hub” que j’ai trouvée est celle-ci:

http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140228.html

Une lecture approfondie est nécessaire, mais vaut la peine si vous devez effectuer des réglages. Particulièrement perspicace est: ergonomie de ramasse-miettes

  1. Est-ce que G1 est le collecteur par défaut de Java 7 et si non, comment puis-je activer G1?

G1 n’est pas un collecteur par défaut dans Java 7. -XX:+UseG1GC activera G1GC

  1. Quels parameters optionnels g1 possède-t-il dans Java7?

Il y a beaucoup de. Jetez un coup d’œil à cet article d’ oracle pour des informations complètes.

Le G1 GC est un ramasse-miettes adaptatif avec des parameters par défaut qui lui permettent de fonctionner efficacement sans modification.

Pour cette raison, personnalisez les parameters critiques

 -XX:MaxGCPauseMillis -XX:G1HeapRegionSize -XX:ParallelGCThreads -XX:ConcGCThreads 

et laisser tous les autres parameters à la valeur par défaut .

Voici une liste des options importantes et leurs valeurs par défaut. Cette liste s’applique à la dernière machine virtuelle Java HotSpot, build 24. Vous pouvez adapter et régler les parameters du GC G1 sur la ligne de commande JVM.

Paramètres par défaut importants:

 -XX:G1HeapRegionSize=n 

Définit la taille d’une région G1. La valeur sera une puissance de deux et peut aller de 1 Mo à 32 Mo. L’objective est d’avoir environ 2048 régions basées sur la taille minimale du segment de mémoire Java.

 -XX:MaxGCPauseMillis=200 

Définit une valeur cible pour le temps de pause maximal souhaité. La valeur par défaut est 200 millisecondes. La valeur spécifiée ne s’adapte pas à votre taille de segment de mémoire.

 -XX:G1NewSizePercent=5 

Définit le pourcentage du tas à utiliser comme minimum pour la taille de la jeune génération. La valeur par défaut est 5% de votre segment de mémoire Java.

 -XX:G1MaxNewSizePercent=60 

Définit le pourcentage de la taille de segment à utiliser comme maximum pour la taille d’une jeune génération. La valeur par défaut est 60% de votre segment de mémoire Java.

 -XX:ParallelGCThreads=n 

Définit la valeur des threads de travail STW. Définit la valeur de n sur le nombre de processeurs logiques. La valeur de n est identique au nombre de processeurs logiques jusqu’à une valeur de 8.

S’il y a plus de huit processeurs logiques, définit la valeur de n sur environ 5/8 des processeurs logiques. Cela fonctionne dans la plupart des cas, sauf pour les systèmes SPARC plus volumineux où la valeur de n peut être d’environ 5/16 des processeurs logiques.

 -XX:ConcGCThreads=n 

Définit le nombre de threads de marquage en parallèle. Définit n à environ 1/4 du nombre de threads parallèles de la récupération de la mémoire (ParallelGCThreads).

 -XX:InitiatingHeapOccupancyPercent=45 

Définit le seuil d’occupation du segment de mémoire Java qui déclenche un cycle de marquage. L’occupation par défaut est de 45% du segment de mémoire Java entier.

 -XX:G1MixedGCLiveThresholdPercent=65 

Définit le seuil d’occupation d’une ancienne région à inclure dans un cycle de récupération de place mixte. L’occupation par défaut est de 65%

 -XX:G1HeapWastePercent=10 

Définit le pourcentage de tas que vous souhaitez gaspiller. La machine virtuelle Java HotSpot ne lance pas le cycle de récupération de place mixte lorsque le pourcentage récupérable est inférieur au pourcentage de perte de stack

 -XX:G1MixedGCCountTarget=8 

Définit le nombre cible de collectes de nettoyage mixtes après un cycle de marquage pour collecter les anciennes régions avec au maximum des données en direct G1MixedGCLIveThresholdPercent. La valeur par défaut est de 8 collectes de mémoire mixtes

 -XX:G1OldCSetRegionThresholdPercent=10 

Définit une limite supérieure pour le nombre d’anciennes régions à collecter lors d’un cycle de récupération de place mixte. La valeur par défaut est 10% du segment de mémoire Java.

 -XX:G1ReservePercent=10 

Définit le pourcentage de mémoire de réserve à garder libre afin de réduire le risque de dépassement de l’espace disponible. La valeur par défaut est 10%. Lorsque vous augmentez ou diminuez le pourcentage, veillez à ajuster le total du tas Java du même montant.

Vous avez reconfiguré de nombreux parameters G1GC, qui ne sont pas requirejs si vous suivez la page de documentation ci-dessus. S’il vous plaît vérifier avec les recommandations ci-dessus en particulier sur ParallelGCThreads et ConcGCThreads , qui doivent être basées sur vos cœurs de processeur. Supprimer la reconfiguration des parameters non nécessaires.

Recommandations d’Oracle:

Lorsque vous évaluez et ajustez G1 GC, gardez à l’esprit les recommandations suivantes:

  1. Taille de la jeune génération : évitez de définir explicitement la taille de la jeune génération avec l’option -Xmn ou toute autre option associée telle que -XX:NewRatio . La fixation de la taille de la jeune génération remplace l’objective de temps de pause cible .

  2. Pause Time Buts: Lorsque vous évaluez ou ajustez une récupération de mémoire, il y a toujours un compromis entre la latence et le débit. Le GC G1 est un ramasse-miettes incrémentiel avec des pauses uniformes, mais aussi plus de temps système sur les threads d’application. L’objective de débit pour le G1 GC est de 90% de temps d’application et de 10% de temps de récupération de place .

  1. Des modifications ont-elles été apscopes à d’autres collectionneurs tels que cms ou le collecteur parallèle de Java 7?

Il y a quelques changements avec Java 7. Jetez un oeil à cet article

  1. Où puis-je trouver une bonne documentation sur la récupération de place dans Java 7?

Reportez-vous à la page de documentation d’Oracle sur gc et la question SE associée:

Ramasse-miettes Java G1 en production

La documentation disponible à l’ adresse http://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html (le lien fourni par Wojtek) semble être le seul lien officiel avec l’info mais l’info semble obsolète car certains des drapeaux mentionnés ne sont disponibles que dans les versions de test, ils n’existent plus dans les versions de production. Quelqu’un d’Oracle devrait fournir une documentation à jour sur le GC G1.

Aucun G1 n’est pas un garbage collector par défaut dans jdk 1.7.0_02. Le récupérateur de place par défaut dépend de la classe de la machine. Si la machine est de classe Server, le ramasse-miettes par défaut est Throughput Collector. Si la machine est de classe Client, le ramasse-miettes par défaut est Serial Collector.

Par défaut, vous ne voulez pas vraiment utiliser le collecteur G1, car il n’est pas vraiment meilleur que les autres. Ce n’est bon que pour des buts spéciaux.

Dans les applications à faible latence, les applications sont légèrement meilleures que les applications CMS, car leur temps de pause est un peu plus court et plus prévisible. En échange, le débit est bien pire que celui du CMS en échange.

Donc, la latence est importante, mais le débit n’est pas important du tout. Si les deux sont importants, restz avec CMS.