一.学习目标
1.了解解释器与编译器的概念与作用。
2.知道jvm中三种执行模式。
3.了解热点代码。
二.解释器模式与编译器模式以及混合模式
字节码文件通过类装载器装载,被分配被分配到JVM的运行时数据区,然后会被执行引擎执行。执行引擎以指令为单位读取Java字节码。它就像一个CPU一样,一条一条地执行机器指令。每个字节码指令都由一个1字节的操作码和附加的操作数组成。执行引擎取得一个操作码,然后根据操作数来执行任务,完成后就继续执行下一条操作码。将人能读懂的字节码文件转化为jvm可以读懂执行的语言,在jvm中通过三种方式经行转化,即解释器模式,JIT编译器模式,混合模式。
1.解释器模式
一条一条地读取,解释并且执行字节码指令。因为它一条一条地解释和执行指令,所以它可以很快地解释字节码,但是执行起来会比较慢,没有JIT的配合下效率不高。
2.JIT编译器模式
即时编译器把整段字节码不加筛选的编译成机器码不论其执行频率是否有编译价值,在程序响应时间的限制下,没有达到最大的优化。
3.混合模式
在解释执行的模式下引入编译执行,刚好可以弥补相互的缺点,达到更优的效果。
程序刚开始启动的时候,因为解释器可以很快的解释字节码,所以首先发挥作用,解释执行Class字节码,在合适的时候,即时编译器把整段字节码编译成本地代码,然后,执行引擎就没有必要再去解释执行方法了,它可以直接通过本地代码去执行它。执行本地代码比一条一条进行解释执行的速度快很多,主要原因是本地代码是保存在缓存里的。
混合模式下其各自的特点主要如下:
解释器:
- 程序启动时首先发挥作用,解释执行Class字节码;
- 省去编译时间,加快启动速度;
- 但执行效率较低;
JIT编译器:
- 程序解释运行后,JIT编译器逐渐发挥作用;
- 编译成本地代码,提高执行效率;
- 但占用程序运行时间、内存等资源;
三.热点代码
在刚开始的时候,jvm不知道这段代码,是否会频繁的调用方法,或是一个循环,也就是这段代码被多次执行,因此刚开始的时候并不会编译代码,将代码翻译成 java 字节码相对于编译这段代码并执行代码来说,要快很多。编译器回去衡量哪些方法会被频繁调用,如果一个方法的执行频率超过一个特定的值的话,那么这个方法就会被JIT编译成本地代码。而这个方法或代码块因其运行特别频繁,就会认为这是“热点代码”(Hot Spot Code)。当 JVM 执行某一方法或遍历循环的次数越多,就会更加了解代码结构,那么 JVM 在编译代码的时候就做出相应的优化。
热点代码分为二类:
- 多次被调用的方法
- 多次被执行的循环体
检测热点代码:
- 方法计数器:记录方法调用的次数
- 回边计数器:记录代码块循环次数
当计数器数值大于默认阈值或指定阈值时,方法或代码块会被编译成本地代码。
四.总结
如上图可以看出,整个java应用程序的执行过程如下:
1、源代码经javac编译成字节码,class文件
2、程序字节码经过JIT环境变量进行判断,是否属于“热点代码”(多次调用的方法,或循环等)
3、如是,走JIT编译为具体硬件处理器(如sparc、intel)机器码
4、如否,则直接由解释器解释执行
参考资料:
https://blog.csdn.net/sinat_37138973/article/details/78438806