Now we know that how
classes are loaded by Class
Loaders, which are part of Class
Loader Sub System, next thing that happens is the execution of those class
files. JVM Execution Engine is the responsible component for this. It has two components:
- Interpreter
- JIT Compiler
Interpreter
- It reads the byte code, interpret it into machine code (native code) and then execute them line by line.
- Problem with interpreter is it interprets every-time even if same method invoked every-time which reduces performance of the system.
- To overcome this problem, "Sun" introduced JIT Compiler in 1.1 version.
JIT Compiler
- Main purpose of JIT Compiler is to improve performance. Internally it maintains a separate count for every method.
- Whenever JVM comes across any method call, first that method will be interpreted normally by interpreter and JIT Compiler increments corresponding count variable.
- This process is done for every method being executed.
- Once any method reaches a threshold value, JIT Compiler identifies that this method is commonly used method. These commonly used methods are also called hot-spot.
- Immediately JIT Compiler compiles that method and generates corresponding native code. Next time, for this method call, generated native code is used directly instead of interpreting it once again.
- Threshold count varies from JVM to JVM.
- Some advanced JIT Compilers recompile generated native code, if count reaches threshold value second time, so that more optimized machine code is generated.
- Internally, profiler, which is part of JIT Compiler is responsible to identify hot-spots.
- One thing to note here is that JVM interprets whole program at least once. JIT compilation is done only for repeatedly used methods, not every method.
With that, we are done with the series for JVM understanding. Please let me know your view and if you want any other topic to be covered.