Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't the JVM compile the entire program up front, instead of compiling it piece-by-piece?

For this thread Herbert Schildt writes:

It is important to understand that it is not practical to compile an entire Java program into executable code all at once, because Java performs various run-time checks that can be done only at run time.

What run-time checks does he mean?

Please explain the reasons of compiling bytecode piece-by-piece, not the entire program.

like image 710
Sergey Avatar asked Apr 26 '11 18:04

Sergey


People also ask

Does JVM compile?

Modern JVMs take bytecode and compile it into native code when first needed. "JIT" in this context stands for "just in time." It acts as an interpreter from the outside, but really behind the scenes it is compiling into machine code.

Why is Java not compiled?

Java is a compiled programming language, but rather than compile straight to executable machine code, it compiles to an intermediate binary form called JVM byte code. The byte code is then compiled and/or interpreted to run the program. Save this answer.

What happens to your code after you ask the JVM to compile the code?

In Java, programs are not compiled into executable files; they are compiled into bytecode (as discussed earlier), which the JVM (Java Virtual Machine) then executes at runtime. Java source code is compiled into bytecode when we use the javac compiler. The bytecode gets saved on the disk with the file extension .

Is JVM enough to run Java program?

You can't run Java program without JVM. JVM is responsible in running a Java program, but the only file that can be executed by JVM is Java bytecode, a compiled Java source code.


3 Answers

There could be several reasons to compile it piece by piece(those are the first two that come to my mind):

  1. Optimisation of a code that is used many times, not all of the code needs to be recompiled, but only the specific part.
  2. Acquisition of classes over the network - sometimes you want to avoid acquiring all the code, since it costs in bandwidth.

And I don't know if this site is accurate, but I learned a lot from it: http://www.artima.com/insidejvm/ed2/index.html

like image 189
MByD Avatar answered Nov 02 '22 23:11

MByD


What he is saying is that it's impractical to compile all the bytecode to machine language at runtime. You could precompile everything, but that's not the approach that JIT takes.

For one thing, there is no knowing how large the program is. People would get fairly upset at a 30 minute startup as it compiled every library it could find (A given Java program isn't in a single file, it has access to everything in the classpath)

For another, even if you told the system exactly what components your program would use, there is no telling how much of your program could be used for a given run--people would get more upset at a 30 minute startup to run a command line program with parameters consisting of "--help"

Finally it can do some great tricks by compiling while it's running. with a method like this:

public testMeh(int param) {
    if(param == 35) 
        do bunches of crap;
    else if (param > 5)
        do much more crap;
    else 
        return;
    }

The compiler can call it once or twice and on the fly recognize that values 5 and under just return. If this is called all the time with a value of 2 it can replace the ENTIRE method call with if (param != 2) testMeh(param);

which eliminates the entire method call for that number. Later it can figure out that not calling that method means certain member variables can't change and that can collapse other portions of the code to nothing.

This is just plain hard as hell if you precompile stuff. I mean you could write exception code everywhere as you recognize patterns but your code would quickly become a nightmare.

Now if you are asking why not precompile the entire program when you compile it into bytecode--that's a different question and not what the quote was addressing at all--but you can do that to. It's been done and works pretty well. You trade portability and runtime flexibility for a quicker start time.

like image 24
Bill K Avatar answered Nov 03 '22 01:11

Bill K


One possible reason: Java runtime is very dynamic environment. Classes are loaded and unloaded all the time. Depending on classes currently in use, certain optimizations are possible or impossible. For example, if you have interface A and single implementation ImplA, all calls to methods in interface A may be changed to use direct calls to ImplA methods, without doing any virtual method stuff. Once another class AnotherImplA is loaded, this kind of optimization is not possible anymore. Once AnotherImplA is unloaded, it's possible again.

There are lot of optimizations in JVM that use data gathered during runtime. Doing all optimizations up-front would miss lot of opportunities.

Check also recent talk from Cliff Click, A JVM Does That?

like image 27
Peter Štibraný Avatar answered Nov 02 '22 23:11

Peter Štibraný