Recently I took part in a discussion over the efficiency of Java. As I listened, plenty of arguments against Java were that interpreting is "extremely time consuming" and because of it even simple Java programs run way slower than similar one's compiled directly to machine code.
An answer to that was that Java code is often compiled directly to machine code, if only JVM calculates it makes program faster than if it was interpreted in a standard way.
My questions are: when does JVM actually "decide" to perform just-in-time compilation? What are the criteria that make JIT more efficient than standard bytecode interpreting? I mean, the compilation takes some time itself, and as far as I understand, it is all supposed to happen when the program is already running?
The Just-In-Time (JIT) compiler is a component of the Java™ Runtime Environment that improves the performance of Java applications at run time. Java programs consists of classes, which contain platform-neutral bytecodes that can be interpreted by a JVM on many different computer architectures.
The JIT compiler converts high-level abstract bytecode to native machine code, while speeding up the execution of the bytecode right when it is supposed to be executed.
A Just-In-Time (JIT) compiler is a feature of the run-time interpreter, that instead of interpreting bytecode every time a method is invoked, will compile the bytecode into the machine code instructions of the running machine, and then invoke this object code instead.
The above loop code runs for 10 times if the value of i is 0. It is not necessary to compile the bytecode for 10 times again and again as the same instruction is going to execute for 10 times. In that case, it is necessary to compile that code only once and the value can be changed for the required number of times.
This varies widely depending on your JVM and its settings. Wikipedia:
For example, Sun's Java Virtual Machine has two major modes—client and server. In client mode, minimal compilation and optimization is performed, to reduce startup time. In server mode, extensive compilation and optimization is performed, to maximize performance once the application is running by sacrificing startup time. Other Java just-in-time compilers have used a runtime measurement of the number of times a method has executed combined with the bytecode size of a method as a heuristic to decide when to compile.[4] Still another uses the number of times executed combined with the detection of loops.[5]
A rough approximation for a vanilla HotSpot JVM in -server mode is that JIT occurs when the JVM notices that a certain method has been called a lot, usually more than some specific number of times. (This is why the JVM is called "HotSpot" -- because it identifies and optimizes "hot spots" in your code.) At this point, the JVM knows a few things:
if
statement is much more common than another, so it can improve branch prediction
List
passed to this method is usually an ArrayList
, so it can make optimizations and inlinings for the specific case of an ArrayList
.Note that if you compiled in advance to machine code, you wouldn't have a lot of this information to optimize with -- the compiler doesn't know in advance which paths tend to be more common than others. But if you wait to do your optimization until you have real-world data, you can make better optimization decisions.
Some more details on what the JIT does are here.
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