Compiling Java source code doesn't produce machine instructions for a specific processor the way compiling C++ does. It produces bytecode — an intermediate instruction set that isn't native to any real CPU, packaged into .class files. That bytecode is what the Java Virtual Machine (JVM) actually runs.

This is the entire mechanism behind "write once, run anywhere." The same .class file, containing the same bytecode, runs unmodified on Windows, Linux, or macOS — on x86-64 or ARM64 — because the JVM, not the bytecode, is what's specific to the platform. Oracle and other vendors ship a different JVM build for each platform, and each one knows how to translate the same universal bytecode into instructions its specific processor understands.

The JVM doesn't just interpret bytecode line by line and stop there, though early implementations mostly worked that way. Modern JVMs use a Just-In-Time (JIT) compiler that watches which methods run frequently — "hot" code paths — and compiles those specific methods down to real native machine code at runtime, so a method called millions of times over a program's execution gets the speed benefit of native compilation without every method needing that treatment.

The JVM also owns memory management: it allocates objects on a managed heap and runs its own garbage collector to reclaim memory automatically, rather than requiring the programmer to explicitly free every allocation, the way C or manually-managed C++ code does. That's part of the platform-independence contract too — memory management behavior is guaranteed by the JVM spec, not left to whatever a given operating system happens to provide.

This layered design — source to bytecode once, bytecode to native instructions per-platform, on demand — is also why a JVM update can improve the performance of already-compiled Java programs without recompiling them at all. The bytecode never changes; only how the JVM chooses to execute it does, which is where most JIT and garbage-collector improvements between JVM versions actually show up.

The full mechanics of bytecode format, class loading, and JIT behavior are specified in detail in Oracle's own Java Virtual Machine Specification, the canonical reference underneath every JVM implementation, including non-Oracle ones like OpenJDK.