JVM执行字节码有两种方式:解释模式(interpreter)和编译模式(jit)。
整个java程序执行过程如下:
- 使用javac把.java源文件编译为字节码,文件一般以.class作为后缀
- 字节码经过JIT环境变量进行判断,是否属于热点代码(多次调用的方法,或循环等)
- 热点代码使用JIT编译为可执行的机器码
- 非热点代码使用解释器解释执行所有字节码
解释器将每个Java指令都转译成对等的微处理器指令,并根据转译后的指令先后次序依序执行,由于一个Java指令可能被转译成十几或数十几个对等的微处理器指令,这种模式执行的速度相当缓慢。
Sun公司为了解决解释器的执行慢的问题,引入了JIT技术。JIT针对一个具体的class进行编译,经过编译后的程序,被优化成相当精简的原生型指令码。
示例
public static void main(String[] args) {
long start = System.nanoTime();
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++){
}
long finish = System.nanoTime();
long d = (finish - start) / 1000000;
System.out.println("Used " + d);
}
上面的循环,使用JIT只需要极少的时间,而禁用JIT后执行速度慢了很多。
$ javac Demo.java
$ java Demo
Used 6
$ java -Djava.compiler=NONE Demo
Used 100030
其中添加-Djava.compiler禁用了JIT,速度相对使用JIT大大降低。