解释器
1.在运行时,通过解释器逐行解释执行程序,其角色就是一个翻译者,将字节码的内容翻译为对应平台的本地机器指令
2.可以分为字节码解释器和模版解释器
1.字节码解释器就是在执行时通过纯软件代码模拟字节码的执行,效率非常低下
2.m模板解释器将每一条字节码和模版函数相关联,直接产生这个字节码执行时的机器码,提高性能
3.在hotspot虚拟机中,解释器主要由Interpreter模板和Code模块组成
1.Interpreter模块:实现了解释器核心功能
2.Code模块:用于管理Hotspot虚拟机运行时生成的本地机器指令
即使编译器
将字节码直接编译成本地机器码之后再执行,这里面涉及到热点探测功能,只有有价值的字节码才会编译为本地机器指令,否则还是会解释执行
HotSpot VM是目前市面上高性能虚拟机的代表作之一,它采用解释器和即使编译器并存的结构。在java虚拟机运行时,解释器和即使编译器能够互相协作,各自取长补短,尽力去选择最合适的方式来权衡编译本地代码的时间
为什么要采用两种方式共同协作的方式?
1.当程序启动后,解释器可以马上发挥作用,省去编译的时间,立即执行,编译器不同,它要发挥作用,把代码编译成本地代码需要一定的执行时间。但是编译为本地代码之后,执行效率很高。(例如JRockit VM尽管执行性能非常高效,但程序启动时必然花费更长的时间来进行编译,对于服务端来说,启动时间并非是关注重点,但对于那些看中启动时间的应用场景而言,或许就需要解释器和即使编译器并存的架构来换取一个平衡点了)
2.采用两者并存的架构时候,当虚拟机启动时,解释器可以首先发挥作用,不必等待即使编译器全部编译完成后再执行,这样可以省去许多不必要的编译时间,随着时间推移,编译器根据热点探测发挥作用,把越来越多的代码编译成本地代码,获得更高的执行效率
3.解释执行在编译器进行激进优化不成立的时候,作为编译器的逃生门
编译器的概念解释
1.前段编译器(javac)
2.JIT编译器(C1,C2)也称后端编译器
3.AOT编译器 静态提前编译器 运行之前直接把字节码文件编译成本地机器码的过程
热点代码以及探测方式
是否需要启动JIT编译器将字节码直接编译为对应平台的本地机器指令,则需要根据代码被调用执行的频率而定。关于那些需要被编译为本地代码的字节码,也称为热点代码,JIT编译器在运行时会针对那些频繁被调用的热点代码作出深度优化,将其直接编译为对应平台的本地机器指令,以此提升java程序的执行性能

这个计数器就用于统计方法被调用的次数,默认阈值在client模式下是1500次,在server模式下是10000次,超过这个阈值,就会触发JIT编译
这个阈值可以通过虚拟机参数 -XX:CompileThreshold来人为设定
当一个方法被调用时,会先检查该方法是否存在JIT编译过版本,如果存在,则优先使用编译后的本地代码来执行,如果不存在已经被编译过的版本,则将此方法的调用计数器值+1,然后判断方法调用计数器与回边计数器值之和是否超过方法调用计数器的阈值,如果已超过阈值,那么将会向即使编译器提交一个该方法的代码编译请求

热度衰减

方法调用计数器就是方法被调用的次数,回边计数器就是统计一个方法中循环体代码执行的次数(在字节码中遇到控制流向后跳转的指令称为"回边" Back Edge)。显然,建立回边计数器统计的目的就是为了触发OSR编译