JVM学习笔记06-执行引擎

目录

1、概述

2、Java代码编译和执行的过程

3、解释器(Interoreter)

4、JIT编译器


PDF版笔记:JVM的学习笔记PDF版-互联网文档类资源-CSDN下载

1、概述

JVM学习笔记06-执行引擎_第1张图片

特点:

  • 执行引擎时JVM的核心部件之一
  • “虚拟机”是相对“物理机”的概念,他们都有代码执行的能力。但是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引擎是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式
  • 执行效率上 虚拟机 < 物理机
  • 执行引擎将字节码翻译成为物理机能够理解的指令,并交由物理机执行

与其余组件的交互:

  1. 执行引擎在执行的过程中究竟需要执行说明字节码指令完全依赖于PC寄存器
  2. 当执行完一项指令操作后,PC寄存器就会更新下一条需要被执行的指令地址
  3. 当方法在执行过程中,执行引擎有可能会通过存储在局部变量表中的对象引用准确定位到存储在Java堆区中的对象实例信息,以及通过对象头中的元数据指针定位到目标对象的类型信息

2、Java代码编译和执行的过程

JVM学习笔记06-执行引擎_第2张图片

橙色部分:根据 javac(前端编译器)

绿色部分:解释执行(解释器)

蓝色部分:编译(JIT)执行

3、解释器(Interoreter)

  • 当JVM启动时会根据预定义的规范堆字节码采用逐行解释的方式执行,将每条字节码文件的内容“翻译”为对应平台的本地机器指令执行
  • 根据PC寄存器获取需要解析的下一条字节码指令
  • 出现过两套执行器:字节码解释器、模板解释器(现在使用)
  • 基于解释器执行整体来说较为低效

4、JIT编译器

  • 就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言
  • JIT编译器的效率相较于解释器更高。
  • C1、C2编译器,这两个编译器的优化效率不一样

热点探测:是否要启动JIT编译器将字节码直接编译成对于平台的本地机器指令,需要根据代码被调用执行的频率而定。关于那些需要被编译成本地代码的字节码也被称热点代码。JIT编译器在运行时,会针对那些频繁被调用的热点代码做出深度优化。那么来执行频率比较高的那个干嘛?

  • 一个被多次调用的方法,或者是一个方法体内部,循环次数较多。都可以被称为热点代码。由于这种编译方式发生在方法的执行过程中。如此也被称为栈上替换或简称为OSR
  • 目前Hotspot VM所采用的热点探测方式是基于计数器的热点探测 (方法调用计数器、回边计数器)

方法调用计数器

  • 用于统计方法的调用次数,在Client模式下是1500次,在Server模式下是10000次,可通过“-XX:CompileThreshold”来设定
  • 如果不做任何设置,当超过一定的时间限度如果方法的调用次数仍不足以让他提交给及时编译器编译那么这个方法的调用技术器就会被减少一半。这个过程被称为方法调用的计数器热入的衰减,而这段时间就被称为此方法统计的半衰周期。
  • “-XX:-UseCounterDecay”来关闭热度衰减,“-XX:CounterHalfLifeTime” 设置半衰周期

回边计数器

  • 用于统计循环体执行的循环次数,在字节码中遇到控制流向后跳转的指令,称为回边。
  • 显然,建立回边计数器统计的目的就是为了触发OSR编译。

设置JVM的程序执行方式:“-Xint”解释器 “-Xcomp”即时编译器 “-Xmixed” 混合模式(默认)

JIT的分类:

-client

  1. 指定JVM运行在Client模式下,并使用C1编译器.C1编译器会对字节码进行简单和可靠的优化,耗时短。以达到更快的编译速度。
  2. 方法内联:讲引用的函数代码编译到引用点处,这样可以减少栈帧的生成,减少参数传递以及跳转过程
  3. 去虚拟化:对唯一的实现类进行内联
  4. 冗余消除:在运行期间把一些不会执行的代码折叠掉

-server

  1. 指定JVm运行在Server模式下,并使用c2编译器.C2进行耗时较长的优化以及激进优化。但优化的代码执行效率更高。
  2. 标量替换:用标量代替聚合对象的属性值
  3. 栈上分配:对于未逃逸的对象分配在栈而不是堆
  4. 同步消除:清除同步操作,通常指synchronized

通过以上指令可以修改,但是64位的操作系统就是Server模式。

Q:为什么明明有了效率更高的JIT编译器,还要保留效率更低的解释器。

A:

  1. 刚程序启动后,解释器可以马上发挥作用,省去编译的时间,立即执行。
  2. 编译器想要发挥作用,需要把代码编译成本地代码。
  3. 需要当Java虚拟机启动时,解释器可以首先发挥作用。而不必带编译器全部编译完成后再执行,这样可以省去许多不必要的编译时间。
  4. 随着时间的推移,编译器发挥作用,把越来越多的代码编译成本地代码。获得更高的执行效率。
  5. 同时,解释执行在编译器进行激进优化不成立的时候。能够作为编译器的后备方案。

你可能感兴趣的:(学习,java,开发语言,jvm)