Java, as a programming language, has attracted a lot of attention with its promise of "write once, run anywhere". However, is the cross-platform experience in reality as perfect as advertised?
The core mechanism of cross-platform capabilities
Cross-platform implementation with Java mainly relies on the Java virtual machine. The source code written by the programmer will be converted by the compiler into an intermediate format, that is, bytecode. The content of this bytecode file with the .class suffix is not designed for specific CPU instruction sets such as Intel or ARM.
There is a unified format of bytecode, which is the key foundation of cross-platform. JVM, as a virtual computer, shoulders the responsibility of reading and executing those bytecode instructions. It is precisely because the JVM gives different operating systems the same running interface that the same bytecode can run on Windows, Linux or macOS.
The role of the Java virtual machine
The core component of the Java runtime environment is the JVM, which focuses on interpreting and executing bytecode, and performs on-the-fly compilation and optimization when needed. JVMs for different platforms are developed by vendors such as Oracle, IBM, and open source communities, and they all follow the same specifications.
This reflects that as long as the corresponding version of the JVM is installed in the target system, the Java program can run. Such a design isolates the program from the underlying hardware and operating system details, greatly simplifying the deployment work of software developers.
From source code to bytecode
The source code file with the .java suffix named .java is the starting point of the Java program. Using the javac compiler proposed in the JDK, these source codes can be compiled into .class files. This compilation process does not generate machine code, but bytecode that the JVM can understand.
Bytecode is an instruction set that is compact and covers all the information needed to run a program. Since it does not depend on a specific platform, after compilation and generation, there is no need to recompile for different systems and can be directly distributed to users.
The composition of JDK and JRE
If you plan to develop Java, you need to install the JDK, which includes a compiler, debugging tools, core class libraries, and a complete JRE. However, if you are an ordinary user and just want to run Java programs, you only need to install a more lightweight JRE, which contains a JVM and a basic class library;
Since JDK version 1.5, when installing JDK in systems such as Windows, environment variables are usually automatically configured. Users do not need to set them manually, and can use javac and java commands on the command line to compile and run operations.
Loading and execution at runtime
When we use the java command to start a program, the JVM will be started first. Then, the JVM's class loader will find and load the .class file containing the main method. During the running of the program, if other classes need to be used, the class loader will dynamically load them into memory.
The JVM interpreter will not interpret and execute multiple bytecode instructions at once, but will interpret and execute them one after another. In order to improve execution efficiency, modern JVMs (such as HotSpot) monitor the frequency of code execution. Codes that are determined to be hot spots will be compiled on-the-fly and converted directly into local machine code. In this way, subsequent execution speed can be improved!
Limitations and extended interactions
The cross-platform features of Java are not without cost. The JVM itself consumes memory and CPU resources, and different platforms have different implementations of the JVM, which may lead to subtle operational differences. For scenarios that require extreme performance or directly operate the hardware, Java sometimes seems unable to cope.
Therefore, Java provides the JNI interface, which allows developers to call native libraries written in languages such as C or C++. In this way, it breaks through the limitations of the virtual machine and achieves high-performance computing or interaction with specific system APIs, but at the same time it also gives up some portability because native libraries are usually platform-related.
During the actual development or use phase, what is the most troublesome problem you encounter when deploying on multiple platforms? It is the difference in environment configuration, the performance is not the same, or other compatibility problems. Welcome to share your experience in the comment area.



