Take a look at the default garbage collector for each version of Java.

  • All information in this article is based on the author’s practice verification, if there is any mistake, please correct, thank you very much.
  • [Java] JVM – default garbage collector for all versions (juejin. Cn)

preface

Operating system information:

Version Windows 11 Home Chinese edition 21H2 Installation Date PF2A6MPG Experience Windows Xp Experience Pack PF2A6MPG Experience Pack 1000.22000.160.0Copy the code

The JDK is introduced:

There are many versions of the JDK, including the Oracle OpenJDK, Such as Adopt-OpenJDK, Amazon Corretto JDK, Azul Zulu CommunityTM JDK, Eclipse Temurin JDK, etc. Even Microsoft has joined the development of JDK 😏.

Different JDKS use different JVMS, so the default garbage collector is used differently. So it’s not surprising, let alone controversial, that the same version of the JDK uses different default garbage collectors. No investigation, no right to speak, but even if the investigation, only the right to speak, not necessarily the right answer. The result of painstaking efforts may only be one side of the Cube, not the whole picture.

Results:

Results in the last chapter, want to see the results of the friends can directly jump to the table of contents.

Query the default garbage collector

Using the Java command

Use -xx :+PrintCommandLineFlags to query variables defined at Java startup to see the GC in use.

PS C:\Program Files\Java> java -XX:+PrintCommandLineFlags -version
-XX:ConcGCThreads=3 -XX:G1ConcRefinementThreads=13 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=257798976 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=4124783616 -XX:MinHeapSize=6815736 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation
java version "16.0.2"2021-07-20 Java(TM) SE Runtime Environment (Build 16.0.2+7-67) Java HotSpot(TM) 64-bit Server VM (build 16.0.2+7-67) 2021-07-20 Java(TM) SE Runtime Environment (Build 16.0.2+7-67) Java HotSpot(TM) 64-bit Server VM (Build 16.0.2+7-67, mixed mode, sharing)Copy the code

Through the code

The code gets the actual garbage collector and uses the default GC as long as no JVM GC parameters are added at run time. Use code:

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;

public class CheckDefaultGC {
    public static void main(String[] args) {
        System.out.println("Get JDK Default GC for jdk"
                + System.getProperty("java.version") + "-"
                + System.getProperty("java.vm.name") + ":");
        for(GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) { System.out.println(gcBean.getName()); }}}Copy the code

Due to Java’s backward compatibility features, older Java programs can run in newer JDKS, so use the JDK5 compiler to compile the program into a class file and then into a JAR package for all JDKS to run.

Don’t trust the results of IDE runs. Some ides add JVM parameters by default, which can be modified or removed, but is a hassle. Using Java commands is the easiest.

  • The MANIFEST. MF:

    Manifest-version: 1.0 Created-By: 1.5.0_22 (Sun Microsystems Inc.) main-class: com.test.checkDefaultgcCopy the code
  • Packaging:

    PS C:\Workspace\Idea\java-test\src> & 'C: \ Program Files \ Java \ jdk1.5.0 _22 \ bin \ javac exe' .\com\test\ checkDefaultgc.java -version javac 1.5.0_22 PS C:\Workspace\Idea\java-test\ SRC > &'C: \ Program Files \ Java \ jdk1.5.0 _22 \ bin \ jar exe' -cfmv check-default-gc.jar .\com\test\CheckDefaultGCManifest.MF .\com\test\ checkDefaultgc.class indicates the manifest increment: com/test/ checkDefaultgc.class (read = 1138) (write = 655)(compress 42%)Copy the code
  • Testing:

    PS C:\Program Files\Java> java -jar C:\Workspace\Idea\java-test\src\check-default-gc.jar
    Get JDK Default GC forJava HotSpot(TM) 64-Bit Server VM: G1 Young Generation G1 Old GenerationCopy the code

Query the default garbage collector

JDK5

JDK5 is a major milestone release of Java, all previous JDK called JDK 1.x, since the fifth release, changed to JDKX named.

Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJdk1.5.0_22 - Java HotSpot(TM) 64-bit Server VM: PS Scavenge PS MarkSweepCopy the code
\jdk1.5.0_22\bin\java.exe -xx :+PrintCommandLineFlags -version -xx :MaxHeapSize=1073741824 -XX:+UseParallelGC -XX:+PrintCommandLineFlags java version"1.5.0 _22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode)
Copy the code
  • MaxHeapSize: indicates the maximum heap size. That is, Xmx, 1073741824 = 1G. The unit is G, m, or K.

  • UseParallelGC: Use the Parallel garbage collector, PS Scavenge and PS MarkSweep.

Note the + sign here, the +/- sign indicates enabled/disabled, and the absence indicates configuration properties.

JDK6

PS C: Program Files\Java>.\jdk1.6.0_45\bin\java.exe -xx :+PrintCommandLineFlags -version -xx :InitialHeapSize=257798976 -XX:MaxHeapSize=4124783616 -XX:ParallelGCThreads=13 -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC -XX:+PrintCommandLineFlags java version"1.6.0 _45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
Copy the code
  • InitialHeapSize: the InitialHeapSize, that is, Xms, 257798976 = 245.8m, can be specified directly in g/ M /k.

  • ParallelGCThreads: the number of ParallelGCThreads that can be set for any multi-threaded GC.

    By default, when the number of cpus is less than 8, ParallelGCThreads is equal to the number of cpus, and when the number of cpus is greater than 8, it is calculated according to the formula: ParallelGCThreads = 8+((n-8)×5/8) = 5×N/8+3 ParallelGCThreads = 8+((n-8)×5/8) = 5×N/8+3

  • +UseCompressedOops: Enables compression of common object Pointers to reduce pointer memory usage.

    CompressedOops for JVM (by CompressedOops)

  • – UseLargePagesIndividualAllocation: closed???

Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJdk1.6.0_45 - Java HotSpot(TM) 64-bit Server VM: PS Scavenge PS MarkSweepCopy the code

JDK7

PS C: Program Files\Java>.\jdk1.7.0_80\bin\java.exe -xx :+PrintCommandLineFlags -version -xx :InitialHeapSize=257798976 -XX:MaxHeapSize=4124783616 -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC -XX:+PrintCommandLineFlags java version"1.7.0 _80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
Copy the code
Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJdk1.7.0_80-java HotSpot(TM) 64-bit Server VM: PS Scavenge PS MarkSweepCopy the code

JDK8

Exe -xx :+PrintCommandLineFlags -version -xx :InitialHeapSize=257798976 PS C: Program Files\Java> -XX:MaxHeapSize=4124783616 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation  -XX:+UseParallelGC -XX:+PrintCommandLineFlags java version"1.8.0 comes with _211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
Copy the code
  • + UseCompressedClassPointers: enable compression type pointer.

    Each object has a pointer to its type in its object header, which is 8 bytes by default on 64-bit operating systems, but can be compressed to 4 bytes with compressed type Pointers enabled, just like UseCompressedOops. At the same time, to enable the compression type pointer, you must enable the compression object pointer first.

Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJdk1.8.0_211 - Java HotSpot(TM) 64-bit Server VM: PS Scavenge PS MarkSweepCopy the code

JDK9

PS C: Program Files\Java>.jdk -9.0.4\bin\java.exe -xx :+PrintCommandLineFlags -version -xx :InitialHeapSize=257798976 -XX:MaxHeapSize=4124783616 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:G1ConcRefinementThreads=13 -XX:-UseLargePagesIndividualAllocation -XX:+PrintCommandLineFlags java version"9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
Copy the code
  • ReservedCodeCacheSize: Sets the maximum code cache size. 251658240 = 240 MB

    The code cache is a separate, often overlooked memory space that stores JIT-compiled native code. Once the code cache is full, JIT compilation stops and the JVM enters full interpreted execution. JIT optimizations are no longer performed on code other than code previously stored in the code cache, equivalent to interpreted language. Speed drops by an order of magnitude, so code cache size is important.

    Also, the native method code (JNI) used by Java is stored in the code cache. If the cache is full, it can also affect the efficiency of local methods.

    The corresponding InitialCodeCacheSize is the starting code cache size.

  • +SegmentedCodeCache: Enable code cache segmentation initialization.

    The code cache is divided into three blocks: NonNMethodCode, ProfiledCode, and NonProfiledCode. If code cache segmentation initialization is not enabled, these three areas are initialized as one whole, and if enabled, they are initialized as three separate areas.

  • +UseG1GC: Enable the GC garbage collector.

  • G1ConcRefinementThreads: G1 Number of buffer threads.

Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJava HotSpot(TM) 64-Bit Server VM: G1 Young Generation G1 Old GenerationCopy the code

JDK10

PS C: \ Program Files \ Java > \ JDK - 10.0.2 \ bin \ Java exe - XX: + PrintCommandLineFlags - version - XX: G1ConcRefinementThreads = 13 -XX:InitialHeapSize=257798976 -XX:MaxHeapSize=4124783616 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation -XX:+PrintCommandLineFlags java version"10.0.2"2018-07-17 Java(TM) SE Runtime Environment 18.3 (Build 10.0.2+13) Java HotSpot(TM) 64-bit Server VM 18.3 (Build) 10.0.2 + 13, mixed mode)Copy the code
Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJava HotSpot(TM) 64-Bit Server VM: G1 Young Generation G1 Old GenerationCopy the code

JDK11

PS C: \ Program Files \ Java > \ JDK - 11.0.11 \ bin \ Java exe - XX: + PrintCommandLineFlags - version - XX: G1ConcRefinementThreads = 13 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=257798976 -XX:MaxHeapSize=4124783616 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation -XX:+PrintCommandLineFlags java version"11.0.11"2021-04-20 LTS Java(TM) SE Runtime Environment 18.9 (Build 11.0.11+9-LTS-194) Java HotSpot(TM) 64-bit Server VM 18.9 (build 11.0.11 + 9 - LTS - 194, mixed mode)Copy the code
  • GCDrainStackTargetSize: Indicates the maximum number of objects that can be marked at one time to ensure the performance of the processing. The default value is 64.
Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJava HotSpot(TM) 64-Bit Server VM: G1 Young Generation G1 Old GenerationCopy the code

JDK12

PS C: \ Program Files \ Java > \ JDK - 12.0.2 \ bin \ Java exe - XX: + PrintCommandLineFlags - version - XX: G1ConcRefinementThreads = 13 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=257798976 -XX:MaxHeapSize=4124783616 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation -XX:+PrintCommandLineFlags java version"12.0.2"Java(TM) SE Runtime Environment (Build 12.0.2+10) Java HotSpot(TM) 64-Bit Server VM (build 12.0.2+10) mixed mode, sharing)Copy the code
Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJava HotSpot(TM) 64-Bit Server VM: G1 Young Generation G1 Old GenerationCopy the code

JDK13

PS C: \ Program Files \ Java > \ JDK - 13.0.2 \ bin \ Java exe - XX: + PrintCommandLineFlags - version - XX: G1ConcRefinementThreads = 13 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=257798976 -XX:MaxHeapSize=4124783616 -XX:MinHeapSize=6815736 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation -XX:+PrintCommandLineFlags java version"13.0.2" 2020-01-14
Java(TM) SE Runtime Environment (build 13.0.2+8)
Java HotSpot(TM) 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)
Copy the code
  • MinHeapSize: Minimum memory occupied by the heap area, 6815736 = 6.5M
Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJava HotSpot(TM) 64-Bit Server VM: G1 Young Generation G1 Old GenerationCopy the code

JDK14

PS C: \ Program Files \ Java > \ JDK - 14.0.2 \ bin \ Java exe - XX: + PrintCommandLineFlags - version - XX: G1ConcRefinementThreads = 13 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=257798976 -XX:MaxHeapSize=4124783616 -XX:MinHeapSize=6815736 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation -XX:+PrintCommandLineFlags java version"14.0.2"Java(TM) SE Runtime Environment (Build 14.0.2+12-46) Java HotSpot(TM) 64-Bit Server VM (Build 14.0.2+12-46) mixed mode, sharing)Copy the code
Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJava HotSpot(TM) 64-Bit Server VM: G1 Young Generation G1 Old GenerationCopy the code

JDK15

PS C:\Program Files\Java>.jdk -15.0.2\bin\java.exe -xx :+PrintCommandLineFlags -version -xx :ConcGCThreads=3 -XX:G1ConcRefinementThreads=13 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=257798976 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=4124783616 -XX:MinHeapSize=6815736 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation java version"15.0.2" 2021-01-19
Java(TM) SE Runtime Environment (build 15.0.2+7-27)
Java HotSpot(TM) 64-Bit Server VM (build 15.0.2+7-27, mixed mode, sharing)
Copy the code
Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJava HotSpot(TM) 64-Bit Server VM: G1 Young Generation G1 Old GenerationCopy the code

JDK16

PS C:\Program Files\Java>.jdk -16.0.2\bin\java.exe -xx :+PrintCommandLineFlags -version -xx :ConcGCThreads=3 -XX:G1ConcRefinementThreads=13 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=257798976 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=4124783616 -XX:MinHeapSize=6815736 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation java version"16.0.2"2021-07-20 Java(TM) SE Runtime Environment (Build 16.0.2+7-67) Java HotSpot(TM) 64-bit Server VM (build 16.0.2+7-67) 2021-07-20 Java(TM) SE Runtime Environment (Build 16.0.2+7-67) Java HotSpot(TM) 64-bit Server VM (Build 16.0.2+7-67, mixed mode, sharing)Copy the code
Exe -jar C:\Workspace\Idea\java-test\ SRC \check-default-gc.jar Get JDK Default GCforJava HotSpot(TM) 64-Bit Server VM: G1 Young Generation G1 Old GenerationCopy the code

record

As you can see, Oracle uses the PS Scavenge and PS MarkSweep for JDK8 and earlier, and the G1 collector for JDK9 and later.

It goes without saying that the ZGC was not replaced immediately due to stability considerations in G1, and JDK17 is the next LTS, which may be changed.

The PS Scavenge and PS MarkSweep were chosen for high throughput and multithreading. Since CMS uses the tag clearing algorithm, it’s really not appropriate to use it as the default.

JDK Version Young GC Old GC LTS
JDK5_22 PS Scavenge PS MarkSweep x
JDK6 PS Scavenge PS MarkSweep x
JDK7 PS Scavenge PS MarkSweep x
JDK8 PS Scavenge PS MarkSweep LTS
JDK9 G1 Young Generation G1 Old Generation x
JDK10 G1 Young Generation G1 Old Generation x
JDK11 G1 Young Generation G1 Old Generation LTS
JDK12 G1 Young Generation G1 Old Generation x
JDK13 G1 Young Generation G1 Old Generation x
JDK14 G1 Young Generation G1 Old Generation x
JDK15 G1 Young Generation G1 Old Generation x
JDK16 G1 Young Generation G1 Old Generation x
JDK17 G1 Young Generation G1 Old Generation x
JDK18 G1 Young Generation G1 Old Generation x
JDK19 G1 Young Generation G1 Old Generation x

Sometimes it takes a lot of time to come to a very simple conclusion. But again, no investigation, no voice. The result is important, but the process is also important.