Simple G1GC tuning
Side notes
Related
https://openjdk.java.net/jeps/304 ⇒ Garbage Collector Interface OpenJDK 10 https://openjdk.java.net/jeps/318 ⇒ Epsilon GC Experimental OpenJDK 11
https://openjdk.java.net/jeps/363 ⇒ Remove CMS OpenJDK 14
Default GC depends on "server class"
If your application is running with less than 2 cpus or less than 2gb of memory the JVM heuristics think the app is not running on a server, which makes the SerialGC the default GC, while this is unlikely to be an issue with apps that use less than 2GB of heap. It may well be an issue for apps that don’t use much CPU but require more memory. In this case it might be useful to toggle UseG1GC.
Corretto 11.0.7 JVM code source :
-
src/src/hotspot/share/runtime/os.cpp:1654-1699
// This is the working definition of a server class machine: // >= 2 physical CPU's and >=2GB of memory, with some fuzz // because the graphics memory (?) sometimes masks physical memory. // If you want to change the definition of a server class machine // on some OS or platform, e.g., >=4GB on Windows platforms, // then you'll have to parameterize this method based on that state, // as was done for logical processors here, or replicate and // specialize this method for each platform. (Or fix os to have // some inheritance structure and use subclassing. Sigh.) // If you want some platform to always or never behave as a server // class machine, change the setting of AlwaysActAsServerClassMachine // and NeverActAsServerClassMachine in globals*.hpp. bool os::is_server_class_machine() {
-
src/src/hotspot/share/gc/shared/gcConfig.cpp:103-117
This method is only used there in this release
void GCConfig::select_gc_ergonomically() { if (os::is_server_class_machine()) { #if INCLUDE_G1GC FLAG_SET_ERGO_IF_DEFAULT(bool, UseG1GC, true); #elif INCLUDE_PARALLELGC FLAG_SET_ERGO_IF_DEFAULT(bool, UseParallelGC, true); #elif INCLUDE_SERIALGC FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true); #endif } else { #if INCLUDE_SERIALGC FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true); #endif } }
This heuristic probably predates containers and cgroups hype, and doesn’t look like it has been updated to reflect this trend.
Anyway it’s always possible to guide the JVM heuristics on this matter, using
-XX:+AlwaysActAsServerClassMachine
(which let’s the default GC be used), or
by enabling a particular GC algorithm.
ZGC
https://openjdk.java.net/jeps/333 ⇒ Experiemental ZGC on OpenJDK 11 https://openjdk.java.net/jeps/351 ⇒ Uncommit on OpenJDK 13
https://openjdk.java.net/jeps/377 ⇒ ZGC is a product feature OpenJDK 15
https://openjdk.java.net/jeps/376 ⇒ Cocurrent Thread-Stack Processing on Open JDK 16
Phase | Serial | Parallel | G1 | CMS | ZGC |
---|---|---|---|---|---|
Marking |
✖︎ |
✖︎ |
✔* |
✔* |
✔ |
Compaction |
✖︎ |
✖︎ |
✖︎ |
✖︎ |
✔ |
Reference Processing |
✖︎ |
✖︎ |
✖︎ |
✖︎ |
✔ |
Relocation Set Selection |
✖︎ |
✖︎ |
✖︎ |
✖︎ |
✔ |
String table cleaning |
✖︎ |
✖︎ |
✖︎ |
✖︎ |
✔ |
JNI WeakRef Cleaning |
✖︎ |
✖︎ |
✖︎ |
✖︎ |
✔ |
JNI GlobalRef Cleaning |
✖︎ |
✖︎ |
✖︎ |
✖︎ |
✔ |
Class Unloading |
✖︎ |
✖︎ |
✖︎ |
✖︎ |
✔ |
Thread Stack Scanning |
✖︎ |
✖︎ |
✖︎ |
✖︎ |
✖︎ |
-
* old gen only
-
** not yet
ZGC has load barrier (inserted by the JIT at strategic places) this barrier checks has a bad color, and fix the object reference.
Currently, ZGC time pause time increase with more threads (GC roots), because this phase is not concurrent. However, work has begun in JEP 376, which shows great progress so far ith sub-millisecond pauses.
Shenandoah
https://openjdk.java.net/jeps/189 ⇒ Shenandoah experimental OpenJDK 12 https://openjdk.java.net/jeps/379 ⇒ Shenandoah is product OpenJDK 15
https://openjdk.java.net/jeps/404 ⇒ Shenadoah generational
https://rkennke.wordpress.com/2013/10/23/shenandoah-gc-brooks-pointers/ https://michdownload.blogspot.com/2021/02/shenandoah-ultra-low-pause-garbage.html https://www.researchgate.net/publication/306112816_Shenandoah_An_open-source_concurrent_compacting_garbage_collector_for_OpenJDK
https://developers.redhat.com/blog/2019/06/27/shenandoah-gc-in-jdk-13-part-1-load-reference-barriers/ https://developers.redhat.com/blog/2019/06/28/shenandoah-gc-in-jdk-13-part-2-eliminating-the-forward-pointer-word/ https://developers.redhat.com/blog/2020/03/04/shenandoah-gc-in-jdk-14-part-1-self-fixing-barriers/ https://developers.redhat.com/blog/2020/03/09/shenandoah-gc-in-jdk-14-part-2-concurrent-roots-and-class-unloading/