Java's GCs are incredible and you have a menu of algorithmic options that let you avoid whatever problem you're worried about.
can these options be used in separate parts of a single app ? e.g. the app I'm developing in C++ has parts that do realtime audio, others that do GPU rendering, others that do classic Qt Widgets GUI, others that do offline computations on datasets - and they all have different performance characteristics and need different memory management schemes to get the best out of each, all while being in a single process; there's reference counting, tree-based allocation, pooled, linear, a GC-ish thing which ensure that memory is freed in specific non-realtime threads... Can that be done with Java or is one tied to a single GC implementation for a given execution of a process?
1. Instant startup due to AOT compilation and a cached heap. Can start faster than C!
2. No warmup.
3. Can create native code shared libraries.
4. Offers isolates, which are segregated heaps that do GC separately but run in-process and which can communicate with each other.
The tradeoffs are that unless you buy the more advanced edition, peak performance is lower due to lack of JIT profiling, you may need to write configs and do other fiddling to ensure the AOT compilation doesn't miss any code that's accessed via reflection, it takes a long time to compile, and you can't dynamically load bytecode (which some libraries do behind the scenes transparently).
Today we've removed CMS, added G1GC, and added ZGC.
G1GC is similar to the parallel in the way it operates but is divided up enough to control for latency.
ZGC is fundamentally different from the parallel collector or G1GC. Suggesting it is the same is to suggest you know nothing of the changes that have happened.