De nombreux ouvrages de référance sur la machine virtuelle Java (JVM) indiquent que, pour le JDK 8 en mode Server, la combinaison par défaut des collecteurs de déchets (Garbage Collectors) est Parallel Scavenge pour la jeune génération et Serial Old (souvent nommé PS MarkSweep) pour l'ancienne génération. Cet article explore la réalité technique derrière cette affirmation à travers une série d'expérimentations.
1. Analyse des drapeaux de la ligne de commande
La première étape consiste à interroger la JVM sur ses paramètres par défaut à l'aide de la commande suivante :
java -XX:+PrintCommandLineFlags -version
Le résultat typique sur un environnement 64 bits est le suivant :
-XX:InitialHeapSize=268435456
-XX:MaxHeapSize=4294967296
-XX:+PrintCommandLineFlags
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:+UseParallelGC
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
On remarque l'activation de l'option -XX:+UseParallelGC. Historiquement, cette option activait Parallel Scavenge + Serial Old. Cependant, nous allons voir que ce comportement a évolué.
2. Exploration via l'API Java Management
Pour identifier les collecteurs réellement instanciés, nous pouvons utiliser les beans de gestion fournis par le JDK. Voici un script simple pour lister les noms des collecteurs actifs :
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.List;
public class ExplorateurGC {
public static void main(String[] args) {
List<GarbageCollectorMXBean> collecteurs = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean gc : collecteurs) {
System.out.println("Collecteur détecté : " + gc.getName());
}
}
}
L'exécution produit généralement :
Collecteur détecté : PS Scavenge
Collecteur détecté : PS MarkSweep
L'ambiguïté réside dans le nom PS MarkSweep. Est-ce un alias pour Serial Old ou pour Parallel Old ? Même en activant explicitement -XX:+UseParallelOldGC, le nom renvoyé par l'API reste identique, ce qui suggère que PS MarkSweep est un identifiant générique pour l'algorithme de marquage-balayage de l'ancienne génération au sein de la famille "Parallel".
3. Distinction par les journaux détaillés (GC Logs)
Pour lever le doute, l'analyse des statistiques de la mémoire après exécution est nécessaier. L'option -XX:+PrintGCDetails permet de visualiser la structure du tas (heap).
java -XX:+UseParallelGC -XX:+PrintGCDetails ExplorateurGC
Dans la sortie, examinez la section relative à l'ancienne génération :
Heap
PSYoungGen total 76288K, used 5243K [...]
eden space 65536K, 8% used [...]
from space 10752K, 0% used [...]
to space 10752K, 0% used [...]
ParOldGen total 175104K, used 0K [...]
object space 175104K, 0% used [...]
Metaspace used 2708K, capacity 4486K, committed 4864K, reserved 1056768K
Le terme ParOldGen confirme l'utilisation de Parallel Old. Si la JVM utilisait Serial Old, nous verrions apparaître PSOldGen.
4. Forcer l'ancien comportement
Si nous désactivons explicitement la compaction parallèle avec -XX:-UseParallelOldGC, le comportement change :
java -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:+PrintGCDetails ExplorateurGC
Résultat dans les logs :
PSOldGen total 175104K, used 0K [...]
Ici, PSOldGen indique que le collecteur série est utilisé pour la vieille génération. Cela prouve que par défaut (quand seul -XX:+UseParallelGC est présent), le JDK 8 préfère la version parallèle.
5. Origine de la confusion
La documentation officielle du JDK 8 précise que la "compaction parallèle" est activée par défaut dès lors que -XX:+UseParallelGC est utilisé sur une machine de classe serveur. Ce changement a été introduit avec la mise à jour JDK 7u4.
Avant cette version, -XX:+UseParallelGC n'activait effectivement que le collecteur parallèle pour la jeune génération. Mais depuis que Parallel Old a été jugé suffisamment stable et performant, il est devenu le partenaire par défaut de Parallel Scavenge. Les ressources pédagogiques plus anciennes ne reflètent pas toujours cette mise à jour majeure du comportement ergonomique de HotSpot.
Synthèse technique
- Combinaison par défaut (JDK 8 Server) :
Parallel Scavenge+Parallel Old. - Drapeau principal :
-XX:+UseParallelGC(qui inclut implicitement-XX:+UseParallelOldGC). - Identification : Le nom JMX
PS MarkSweepest trompeur ; seule la mentionParOldGendans les logs GC garantit l'utilisation du mode parallèle pour l'ancienne génération.