JVM 类执行机制:解释执行(interpreter)和编译执行(JIT)

JVM执行字节码有两种方式:解释模式(interpreter)和编译模式(jit)。

整个java程序执行过程如下:

  1. 使用javac把.java源文件编译为字节码,文件一般以.class作为后缀
  2. 字节码经过JIT环境变量进行判断,是否属于热点代码(多次调用的方法,或循环等)
  3. 热点代码使用JIT编译为可执行的机器码
  4. 非热点代码使用解释器解释执行所有字节码

解释器将每个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大大降低。

版权声明:著作权归作者所有。

相关推荐

在React JSX内部执行循环

这里实现一个表格组件来演示如何在React的JSX内部执行循环。案例假设有一个表格组件,和一个行组件<ObjectRow />,现在需要在表格组件里循环生成行组件<ObjectRow />。是不能直接在jsx里使用for循环,这里介绍两种方法:map函数和立即执行函数。方法一:使用map函数render: function ()&nb

MySQL开启general_log查看执行的SQL语句

general log会记录下发送给MySQL服务器的所有SQL记录,因为SQL的量大,默认是不开启的。一些特殊情况(如排除故障)可能需要临时开启一下。开启MySQL的general logMySQL有三个参数用于设置general log:general_log:用于开启general log。ON表示开启,OFF表示关闭。log_output:日志输出的

配置JVM查看JIT编译机器码

JVM配置查看JIT编译机器码的选项:-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly 查看特定的方法-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod

MyBatis执行MySql批量插入数据

MySQL批量插入数据语法为:insert into my_table(field1, field2, field3) values ("f1_vaule1","f2_vaule1","f3_vaule1"), ("f1_vaule2","f2_vaule2"

撤回Angular CLI执行的ng eject

使用angular cli执行ng eject后,就不允许执行ng server或ng build。执行ng server 或ng build会报一下错误:An ejected project cannot use the build command