参考 http://blog.csdn.net/sunxianghuang/article/details/52094859
- 首先JIT编译器的输入是字节码,输出是机器码(或曰本地代码)。JIT编译与解释器是有点竞争关系的,在不同的场景下分别使用JIT或者解释器。说JIT比解释快,其实说的是“执行编译后的代码”比“解释器解释执行”要快,并不是说“编译”这个动作比“解释”这个动作快。
- 当方法被调用频率不高时,比如构造器,就采用解释执行;反之,进行JIT编译成机器码。
- 如何判定调用频率高不高,HotSpot使用了两个计数器:
1.方法调用计数器:顾名思义,这个计数器用于统计方法被调用的次数。
当一个方法被调用时,会先检查该方法是否存在被JIT编译过的版本,如果存在,则优先使用编译后的本地代码来执行。如果不存在已被编译过的版本,则将此方法的调用计数器值加1,然后判断方法调用计数器与回边计数器值之和是否超过方法调用计数器的阈值。如果超过阈值,那么将会向即时编译器提交一个该方法的代码编译请求。
如果不做任何设置,执行引擎并不会同步等待编译请求完成,而是继续进行解释器按照解释方式执行字节码,直到提交的请求被编译器编译完成。当编译工作完成之后,这个方法的调用入口地址就会系统自动改写成新的,下一次调用该方法时就会使用已编译的版本。
2.回边计数器:它的作用就是统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为“回边”。 - 和解释器相比,JIT编译器的开销是编译+执行的时间,而解释器只有解释执行的时间,无论JIT编译和执行再快,都是比直接解释执行要慢的
- HotSpot虚拟机内置了两种JIT编译器,分别为Client Compiler:追求编译速度和Server Compiler:追求编译质量。