Java, by nature of its moving GCs, can often do better with long running applications than languages like C and C++ which can much more easily suffer from internal memory fragmentation. You can work around it by using tricks like memory pools, using a sophisticated malloc implementation, etc., but that all is much higher effort than with Java.
Additionally, a lot of the systems you mentioned can often benefit from the sophistacted dynamic classloader the JVM provides. For something like Spark (mentioning this one because I am familiar with it), it is a requirement to load and run user specified code dynamically. You can do this in C, but the JVM makes this much easier.
Yes, it's really more about the GCs than the JIT. The yak-shaving involved in a performant C++ app is an order of magnitude higher. Plus, you get nice stack traces. Libraries like Netty make for extremely high-throughput apps.
Additionally, a lot of the systems you mentioned can often benefit from the sophistacted dynamic classloader the JVM provides. For something like Spark (mentioning this one because I am familiar with it), it is a requirement to load and run user specified code dynamically. You can do this in C, but the JVM makes this much easier.