Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly is the JIT compiler inside a JVM?

Tags:

java

jvm

I'm trying to understand how Java source code is executed and I'm confused as to what the JIT-compiler inside the JVM actually is. To start off let me tell you how I understand the process of going from Java source code to executing machine code on a computer. Perhaps, I'm misunderstanding something in the process that is causing the confusion.

The steps:

  1. The source code is compiled into bytecode (.class files)
  2. The class files are loaded into the JVM (which is in RAM)
  3. the bytecode is verified and then processed by the JIT compiler
  4. the output of the JIT compiler is machine code ready for execution

Now, according to the Wikipedia article on JVM, and more specifically the "Bytecode interpreter and just-in-time compiler" section, in order to execute Java bytecode you need an interpreter (but we have a JIT compiler).

Now here's the bit that is confusing to me. I've broken it down into quotes:

"When Java bytecode is executed by an interpreter, the execution will always be slower than the execution of the same program compiled into native machine language."

  1. Since the computer can only execute machine code, and an interpreter is slower at translating the bytecode to machine code than a compiler is, why does the JVM use an interpreter and not a compiler?

  2. Why do we not have another intermediate executable file generated by the JIT compiler for the CPU so it can quickly execute the instructions?

"A JIT compiler may translate Java bytecode into native machine language while executing the program. The translated parts of the program can then be executed much more quickly than they could be interpreted. This technique gets applied to those parts of a program frequently executed."

Is the JIT compiler really an interpreter that has the ability to compile frequently executed code? Are the terms compiler and interpreter wrongfully used interchangeably?

Thanks in advance.

like image 980
ribarcheto94 Avatar asked Jan 06 '17 01:01

ribarcheto94


1 Answers

Since the computer can only execute machine code, and an interpreter is slower at translating the bytecode to machine code than a compiler is, why does the JVM use an interpreter and not a compiler?

Because compiling to machine code also takes time, especially when it has to analyze the code to optimize it, so interpreting is fast enough to execute most of the time, and actually faster than compile+run if only run once/occationally.

Also, an interpreter doesn't "translating the bytecode to machine code". It evaluates the bytecode and performs the operations requested by the bytecode. The interpreter itself is machine code, but it doesn't translate bytecode, it interprets/evaluates the bytecode.

Why do we not have another intermediate executable file generated by the JIT compiler for the CPU so it can quickly execute the instructions?

That would violate the Write Once, Run Anywhere paradigm of Java.

Is the JIT compiler really an interpreter that has the ability to compile frequently executed code?

No, the JIT compiler (or more accurately, the HotSpot compiler, as mentioned by EJP) is a compiler executed by the JVM as needed.

Are the terms compiler and interpreter wrongfully used interchangeably?

Correct. They cannot be used interchangeably, since they don't do the same thing. The interpreter executes bytecode. The JIT/HotSpot compiler converts bytecode to machine code, but doesn't run it.

like image 56
Andreas Avatar answered Nov 09 '22 01:11

Andreas