Except it's not good enough. Every JVM project I've worked on had to work around the unpredictability of the VM: doing things like on a new deploy hitting all your endpoints a 100 times in order to warm things up. Or the curious cases when a trivial change in one part of your program somehow affects the performance characteristics of another. VMs don't provide enough benefits to justify the large burden of actually using them effectively.