执行引擎

  • 执行引擎是Java虚拟机核心的组成部分之一

  • “虚拟机”是一个相对于”物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器,缓存,指令集和操作系统层面上的,而虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式

  • JVM的主要任务是负责装载字节码到内部,但字节码并不能够直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅是一些能够被JVM所识别的字节码指令,符号表,以及其他辅助信息

  • 那么,如果想要让一个Java程序运行起来,执行引擎的任务就是将字节码指令解释/编译为对应平台上的本地机器指令才可以.简单来说,JVM的执行引擎充当了将高级语言翻译为机器语言的译者

image-20200622085814191

java代码编译和 执行的过程

image-20200622085956826

image-20200622090146595

问题:什么是解释器,什么是JIT编译器?

解释器:当Java虚拟机启动的时候会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容”翻译”为对应平台的本地机器指令执行

JIT编译器: 就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言

问题:为什么说Java是半编译半解释型语言?

JDK1.0时代,将Java语言定位为”解释执行”还是比较准确的.再后来,Java也发展出可以直接生成本地代码的编译器

现在JVM在执行java代码的时候,通常会将执行与编译执行二者结合起来进行

机器码 指令 汇编语言

image-20200622090810212

image-20200622090840321

image-20200622090922286

image-20200622091046126

image-20200622091148768

image-20200622091259613

解释器

image-20200622091528313

image-20200622091810159

image-20200622091829241

image-20200622092024828

JIT编译器

image-20200622092218316

image-20200622092239249

image-20200622092340172

JRocket 不包含解释器

image-20200622093612787

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @author shkstart shkstart@126.com
* @create 2020 10:35
*/
public class JITTest {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();

for (int i = 0; i < 1000; i++) {
list.add("让天下没有难学的技术");

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}

image-20200622093937004

image-20200622094115865

image-20200622094132097

image-20200622094306079

image-20200622094625113

image-20200622094948458

设置HotSpot模式

image-20200622095033795

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* 测试解释器模式和JIT编译模式
* -Xint : 6520ms
* -Xcomp : 950ms
* -Xmixed : 936ms
* @author shkstart shkstart@126.com
* @create 2020 12:40
*/
public class IntCompTest {
public static void main(String[] args) {

long start = System.currentTimeMillis();

testPrimeNumber(1000000);

long end = System.currentTimeMillis();

System.out.println("花费的时间为:" + (end - start));

}

public static void testPrimeNumber(int count){
for (int i = 0; i < count; i++) {
//计算100以内的质数
label:for(int j = 2;j <= 100;j++){
for(int k = 2;k <= Math.sqrt(j);k++){
if(j % k == 0){
continue label;
}
}
//System.out.println(j);
}

}
}
}

image-20200622095636413

image-20200622100113861

image-20200622100156810

image-20200622100338777

image-20200622100525612

image-20200622100701027