JVM基础Round 2 | 源代码到机器码的过程中JVM扮演了什么角色

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-21 15:22   95   0

目录

从源码到机器码

1. 源代码到字节码

2.字节码到机器码

3.编译器分类


从源码到机器码

JVM的作用是翻译,将字节码文件翻译成各个系统可识别的机器码。那么我们从代码到机器可识别的机器码的过程中,具体又是怎么回事呢?从上一篇就可以看出,其实这个过程主要是分为两个步骤:一个是源代码转换成字节码,二是字节码转换成机器码

1. 源代码到字节码

上篇末尾有提到,JVM编译的不是java源代码而是字节码,那么我们的源代码是怎么变成字节码的呢?我们知道JDK中附带了一系列的开发、诊断工具。其中javac就是工具之一,我们将它称之为编译器,也就是它将Java代码翻译成字节码。

在我们运行程序的过程中就能发现,我们创建一个类的时候,这个类的文件末尾是.java,一但启动程序,在IDEA目录中会有一个target文件夹,这里面的文件就是编译后的文件,文件后缀变成了.class。在我们将java文件转换成字节码文件的这个过程相对于整个流程是很靠前的一个步骤,因此这个步骤使用到的编译器叫做前端编译器。常见的前端编译器比如我们刚刚提到的javac还有eclipse JDT中的增量式编译器ECJ。我们运行 javac 命令的过程,其实就是 javac 编译器解析 Java 源代码,并生成字节码文件的过程。说白了,其实就是使用 javac 编译器把 Java 语言规范转化为字节码语言规范。javac 编译器的处理过程可以分为下面四个阶段:

2.字节码到机器码

当字节码想要运行的时候,有两种选择:一是通过Java解释器解释执行字节码,二是通过JIT编译器将字节码转化为本地机器码。关于两种方式对比:

这两种方式的区别在于,Java解释器启动速度快但运行速度慢,而JIT编译器启动速度慢但运行速度快。其原因很简单,因为解释器不需要像 JIT 编译器一样,将所有字节码都转化为机器码,自然就少去了优化的时间。而当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。在实际使用的过程中,往往会采取两者相结合使用的方式:

在HotSpot虚拟机中就内置了两个即时编译器,分别是Client CompilerServer Compiler,这两种编译器分别衍生出两种编译模式,我们称之为C1编译模式C2编译模式

关于两种模式对比:

那么我们到底选择C1编译模式还是C2编译模式呢?对于HotSpot 虚拟机来说,其一共有三种运行模式可选:

默认的是混合模式,打开控制台输入命令java -version可以看到版本信息后有标注mixed mode:

以上便是大致上从源代码到机器码中的过程,我们提及到前端编译器和JIT编译器,那么顺便将这部分使用的编译器进行总结吧

3.编译器分类

编译器除了上述的前端编译器和JIT编译器以外,还有常见的一个是AOT编译器

AOT 编译器的基本思想是:在程序执行前生成 Java 方法的本地代码,以便在程序运行时直接使用本地代码。但Java 语言本身的动态特性带来了额外的复杂性,影响了 Java 程序静态编译代码的质量。例如 Java 语言中的动态类加载,因为 AOT 是在程序运行前编译的,所以无法获知这一信息,所以会导致一些问题的产生。因此总的来说:

编译速度解释执行 > AOT 编译器 > JIT 编译器

编译质量JIT 编译器 > AOT 编译器 > 解释执行

啊,暂时先写到这儿吧,我真的画图烂透了,但是又觉得画图比整篇整篇的文字好理解一些,电影快开场了,溜了。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP