This week we’ll look at some of the internals of the Java Virtual Machine (JVM), being the bytecode interpreter and the Just in Time compiler (JIT).
Machine code
Let’s first revise what we know about machine code, programming languages and the process of translating a program into machine code.
Computers only understand machine code which consists of a set of CPU instructions. Each CPU type has its own instruction set which makes machine code non-portable and highly CPU-specific.
Programming languages are designed to be easier to use, more portable than machine code, and less dependent on the actual CPU on which we want the program to run.
We can classify programming languages according to their level of abstraction.
- Machine code is the least abstract and hardest to code.
- Assembler has a slightly higher level of abstraction and is regarded as a low-level language.
- High-level languages allow us to write code at a much higher level of abstraction. Most of the commonly used languages are high-level languages. These include Fortran, Pascal, C, C++, C#, Java, Python, etc.
Interpreters and Compilers
Before we can execute a program written in a high-level language, we need to translate it to native machine code. There are a number of ways to do this:
-
We can use an interpreter. An interpreter reads, translates and runs the source code one line at a time. Each line is translated into CPU instructions on-the-fly and then executed. If there is an error in a line, it will only appear when that line is translated and run. Every time we run the program the interpreter has to repeat these steps. Interpreted languages are usually slower than compiled languages due to the overhead of the interpreter.
-
We can use a compiler. A compiler translates the source code into executable machine code. Compilation is done once before running the program. The compiler first checks for correct language syntax and then converts the program to machine code. After compilation, the executable program can be run as many times as needed without having to be recompiled. Compiled languages tend to run faster, as the program statements do not have to be translated into machine code at runtime.
-
A third option combines compilation and interpretation to get the best of both worlds.
Whether a language is interpreted or compiled is not a feature of the language itself, but is a feature of the specific language implementation. For most languages, implementations are either one type or the other. So we can usually say a language is either interpreted or compiled. However, there are some languages with usable implementations of both types.
Bytecode
Java is a compiled language. There is a separate, preliminary step of compiling the Java source code before being able to run it. The compiler does not compile to low-level native machine code, but compiles to a higher-level, machine-independent, intermediate code representation called bytecode.
Java code is compiled to intermediate bytecode using the javac
compiler. This is a one-time step that we do not need to repeat unless we modify our code. We pass the compiled bytecodes to the JVM to run. This allows the same compiled .class
file to be run on different platforms without being re-compiled.
How does the JVM run this bytecode?
On all JVMs, bytecode can be directly executed by an interpreter. The interpreter parses the bytecode line by line and then directly executes these instructions. Interpreted code always runs slower due to the overhead of the interpreter.
Depending on the JVM version, the bytecodes can be further compiled into machine code at runtime by using a Just-In-Time compiler (JIT). This improves runtime performance. The JIT compiles the bytecodes directly into native machine code. This can give speeds very close to ahead-of-time (AOT) compilation.
Ending Off
In next week’s post, we’ll look at the JIT and Hotspot compiler in more detail.
Don’t forget to share your comments and Java experiences.
1 thought on “JVM Interpreter versus Just-In-Time Compiler”
Pingback: JVM and JIT Command Line Options • 2022 • Incus Data Programming Courses