Earlier quoted context omitted.
Java can be performant, but still typically has a huge footprint and memory profile. Others will point out that there are multiple implementations of Java, which is true, but to what adoption? IMO, the only thing propping up Java is legacy enterprise and Android. The adoption of Go, Rust, et al show that people just aren't that into VMs anymore. They had a place in the self hosted world, but in the microservice/cloud…
A key difference between an ELF binary and a Java .jar is that ELF contains a process image. The loader literally mmaps portions of the executable file into memory, and control is immediately translated to this image (dynamic linking and runtime relocations complicate this a bit, but mainly involve patching the image). Java on the other builds its process image on the heap, using the executable file as input. Nothing…
OAT, in turn, is a playful anagram of AOT, because what Android now does is even more powerful than the JVM or ELF. Android includes a JIT but it also does nightly profile guided optimizations. So not only does Android perform the preloading optimization you mention for ELF but as the user continues to use their apps Android will continue to optimize the compiled binaries.