But the thing is, I can switch GC implementation according to my needs.
If throughput is my number 1 concern I can use ParalellGC, if not I can use ZGC. Or G1 if I want something in between (not sure if the paper picks up the huge drop in overhead of G1 in Java 18).
You can switch the GC implementation only globally. In languages like C++ or Rust you can have different parts of program using different memory management strategy, from carefully hand-crafted region allocation through refcounting to even tracing GC (rarely needed though).