1.JVM、JRE和JDK区别

1.JVM( Java Virtual Machine ):
  • Java虚拟机,它是整个 Java 实现跨平台的最核心的部分,所有的 Java 程序会首先被编译为 .class 的类文件,这种类文件可以在虚拟机上执行,也就是说 class 并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。
  • JVM与java无关,JVM只与class文件格式有关,任何语言只要能编译成class文件格式,就能在JVM上执行
2.JRE(Java RunTime Environment )
  • 组成:虚拟机、java核心类库,是运行环境,不具备编译开发功能
  • 介绍:JRE是运行Java程序所必须环境的集合,包含JVM标准实现及 Java基本类库。它包括Java虚拟机、Java平台核心类和支持文件。它不包含开发工具(编译器、调试器等)。
3.JDK(Java Development Kit):
  • 组成部分:java程序语言设计、虚拟机、java类库,JDK是支持程序开发的最小环境。
  • 介绍:JDK是Java开发工具包,它提供了Java的开发环境(提供了编译器javac等工具,用于将java文件编译为class文件)和运行环境(提 供了JVM和Runtime辅助包,用于解析class文件使其得到运行)。如果你下载并安装了JDK,那么你不仅可以开发Java程序,也同时拥有了运行Java程序的平台。
区别:
  1. JVM不能单独执行.class文件,在解释class 的时候 JVM 需要调用解释所需要的类库lib。
  2. JRE有一个lib目录和bin目录,lib目录里面就是java类库(打成jar包),bin目录就是虚拟机,虚拟机在解释class文件时需要调用到lib目录中的java类库。(JRE=JVM+lib)
  3. JDK包含JRE和开发工具、编辑器等,通过JDK中的javac将.java文件编译成.class文件,交给JVM处理。

2.说说java编译过程

  1. .java源文件通过编译器(javac.exe)编译成.class文件
  2. JVM通过ClassLoader对.calss文件进行解释(自解码解释器和JIT即使编译器)—该过程需要调用核心类库

java解析器编译器是 jdk编译器和解释器_jvm

3.说说JVM内的解释器(Just In Time Compiler)和即时编译器(JIT)

  • 解释器和即时编译器(Just In Time Compiler,JIT)就是JVM中将字节码转化为机器码的工具。
  • 解释器: 解释器将字节码解析成集器能识别的机器码。解释方式是一行一行的读取,解释到哪就执行到哪。
  • 即使编译器:以方法为单位,将热点代码的字节码一次性转为机器码,并在本地缓存起来的工具。避免了部分代码被解释器逐行解释执行的效率问题。

什么是机器码

机器码就是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。

热点代码指的是什么

  1. 多次被调用的代码
  2. 被多次执行的循环体

4.怎么判断方法是否就是热点代码

使用热点代码探测方法

  • 基于采样式的热点探测(Sample Based Hot Spot Detection)
  • 基于计数器的热点探测(Counter Based Hot Spot Detection):(1)方法调用计数器(Invocation Counter )回边计数器(Back Edge Counter )。

采样式的热点探测(Sample Based Hot Spot Detection)

虚拟机会周期性 对各个线程的栈顶进行检查,如果某些方法经常出现在栈顶,这个方法就是“热点代码”。

  • 优点:简单高效。
  • 缺点:容易受到线程阻塞或其他因素影响

方法调用计数器(Invocation Counter )

首先是方法调用计数器。Client 模式下默认阈值是 1500 次,在 Server 模式下是 10000次,这个阈值可以通过 -XX:CompileThreadhold 来人为设定。如果不做任何设置,方法调用计数器统计的并不是方法被调用的绝对次数,而是一个相对的执行频率,即一段时间之内的方法被调用的次数。当超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给即时编译器编译,那么这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器热度的衰减(Counter Decay),而这段时间就成为此方法的统计的半衰周期( Counter Half Life Time)。进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的,可以使用虚拟机参数 -XX:CounterHalfLifeTime 参数设置半衰周期的时间,单位是秒。整个 JIT 编译的交互过程如下图。

java解析器编译器是 jdk编译器和解释器_jvm_02

回边计数器(Back Edge Counter )

作用是统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为“回边”( Back Edge )。显然,建立回边计数器统计的目的就是为了触发 OSR 编译。关于这个计数器的阈值, HotSpot 提供了 -XX:BackEdgeThreshold 供用户设置,但是当前的虚拟机实际上使用了 -XX:OnStackReplacePercentage 来简介调整阈值。

java解析器编译器是 jdk编译器和解释器_jvm_03

5.解释器(Just In Time Compiler)和即时编译器(JIT)如何相互配合

  • 解释器:程序执行的时候,解释器首先发挥作用,省去了编译器编译时间,加快程序的执行焦虑
  • 编译器:在程序运行过程中,随着时间的推移,编译器就开始慢慢发挥了作用,把热点代码编译成本地代码后,以后执行相同的代码,即可直接获取,更高的执行效率。
  • 解释器和编译器相互配合,使程序高效执行。