I am running java on very similar VMs and I can't find the explanation why the SerialGC is chosen over G1GC in one case. It's the same Java version, same OS, same VM instance type on AWS, and I suspect the only difference is container settings but I do not know how to pinpoint what changes. Is there a way to get an explanation on why the VM decides to chose this settings or another?
Java version in both case:
java version "10.0.1" 2018-04-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)
When running java in one case:
java -XX:+PrintFlagsFinal -XX:+PrintCommandLineFlag
output:
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
-XX:InitialHeapSize=253366976 -XX:MaxHeapSize=4053871616 -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseSerialGC
[Global flags]
(...)
bool UseG1GC = false {product} {default}
bool UseParallelGC = false {product} {default}
bool UseSerialGC = true {product} {ergonomic}
And the other:
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
-XX:G1ConcRefinementThreads=8 -XX:InitialHeapSize=253480064 -XX:MaxHeapSize=4055681024 -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC
[Global flags]
(...)
bool UseG1GC = true {product} {ergonomic}
bool UseParallelGC = false {product} {default}
bool UseSerialGC = false {product} {default}
Comparing G1 with CMS reveals differences that make G1 a better solution. One difference is that G1 is a compacting collector. Also, G1 offers more predictable garbage collection pauses than the CMS collector, and allows users to specify desired pause targets.
Yield that ZGC unexpectedly has higher throughput and longer total execution time than G1GC, and other attributes are in line with expectations. According to the results, ZGC has a better overall performance than G1GC under the testing circumstances.
Serial GC is very similar to Parallel GC except that it does all its work in a single thread. The single-threaded approach allows for a less complex GC implementation and requires very few external runtime data structures. The memory footprint is the lowest of all HotSpot collectors.
The G1 GC is a regionalized and generational garbage collector, which means that the Java object heap (heap) is divided into a number of equally sized regions. Upon startup, the Java Virtual Machine (JVM) sets the region size. The region sizes can vary from 1 MB to 32 MB depending on the heap size.
{ergonomic}
in -XX:+PrintFlagsFinal
means that the flag was set automatically based on the number of available processors and the amount of RAM.
JDK 10 treats machine as "server" if it has at least 2 available CPUs and 2 GB RAM. This can be overriden by
-XX:+AlwaysActAsServerClassMachine
or -XX:+NeverActAsServerClassMachine
JVM flags.
"Server" configuration assumes G1 as the default GC, while "Client" machine uses SerialGC by default.
To calculate the number of available processors JDK uses not only the CPUs visible in the OS, but also processor affinity and cgroup limits, including
Since you run Java in a container, it's likely that container imposes cgroup limits that result in a smaller number of available CPUs or amount of memory. Use -Xlog:os+container=trace
to find the effective limits in each particular environment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With