I have come across a few references regarding the JVM/JIT activity where there appears to be a distinction made between compiling bytecode and interpreting bytecode. The particular comment stated bytecode is interpreted for the first 10000 runs and compiled thereafter.
What is the difference between "compiling" and "interpreting" bytecode?
With bytecode, the source code must be compiled only once. The platform-specific interpreter then converts it to machine code that can be executed by the OS and central processing unit, or CPU.
The ExecutionEngine decodes the bytecode and performs the actions necessary to implement each instruction. Its interface is quite simple, consisting of a single function that takes a Context as an argument, and executes the method whose frame is on top of the Context's call stack.
Compiled languages are converted directly into machine code that the processor can execute. As a result, they tend to be faster and more efficient to execute than interpreted languages. They also give the developer more control over hardware aspects, like memory management and CPU usage.
The Java source code first compiled into a binary byte code using Java compiler, then this byte code runs on the JVM (Java Virtual Machine), which is a software based interpreter. So Java is considered as both interpreted and compiled. The compiled byte code allows JVM to be small and efficient, and fast performing.
Interpreting byte code basically reads the bytecode line by line, doing no optimization or anything, and parsing it and executing it in realtime. This is notably inefficient for a number of reasons, including the issue that Java bytecode isn't designed to be interpreted quickly.
When a method is compiled, the JIT loads the whole method and generates native code to run directly on the CPU, rather than reading and interpreting the byte code line by line. After the method is compiled once, the generated native code gets used directly every time the method is called. This is astronomically faster, but incurs some overhead when the method gets compiled; among other things, the JVM is responsible for only compiling frequently called methods, to minimize the overhead while maximizing the performance of "tight inner loop" code that gets called extremely often.
When the bytecode is interperted, it is executed through the JVM interpreter, not directly on the processor, when it is compiled, it is compiled to native machine language and executed directly on the CPU.
The JVM has the Just In Time (JIT compiler); portions of the code that are repeated enough may be compiled into the native assembler code to speed it up.
Note that the change is done in the JVM only, the class (jar/war) files are not changed and remain as bytecode.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With