总编译流程
源码--javac->字节码文件-->被加载到JVM-->JIT-->机器码文件-->操作系统执行
前期 后期
1.前端编译器 2.后端编译器
可通过java解释器解释执行 即时编译器
3.AOT 编译器:一步到位,源代码到机器码
一般是前后端编译器混合使用,前期编译成字节码,后期编译成机器码,AOT用的比较少。
相关问答
- 当源代码转化为字节码之后,其实要运行程序,有两种选择。一种是使用 Java 解释器解释执行字节码,另一种则是使用 JIT 编译器将字节码转化为本地机器代码。
- 前者启动速度快但运行速度慢,而后者启动速度慢但运行速度快。
- javac是前端编译器,java是与javac相对的解释器,解释执行javac编译成的字节码
- 解释器不需要像 JIT编译器一样,将所有字节码都转化为机器码,自然就少去了优化的时间。而当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。
- 机器码的运行效率肯定是高于 Java 解释器的。所以在实际情况中,为了运行速度以及效率,我们通常采用两者相结合的方式进行 Java 代码的编译执行。
- HotSpot 虚拟机内置了两个即时编译器(统称JIT编译器),分别称为 Client Compiler 和Server Compiler。这两种不同的编译器衍生出两种不同的编译模式,我们分别称之为:C1 编译模式,C2 编译模式。
- 那么 C1 编译模式和 C2 编译模式有什么区别呢?
C1 编译模式会将字节码编译为本地代码,进行简单、可靠的优化,如有必要将加入性能监控的逻辑。而 C2 编译模式,也是将字节码编译为本地代码,但是会启用一些编译耗时较长的优化,甚至会根据性能监控信息进行一些不可靠的激进优化。
简单地说 C1 编译模式做的优化相对比较保守,其编译速度相比 C2 较快。而 C2 编译模式会做一些激进的优化,并且会根据性能监控做针对性优化,所以其编译质量相对较好,但是耗时更长。
- 那么到底应该选择 C1 编译模式还是 C2 编译模式呢?
实际上对于 HotSpot 虚拟机来说,其一共有三种运行模式可选,分别是:
混合模式(Mixed Mode) 。即 C1 和 C2 两种模式混合起来使用,这是默认的运行模式。如果你想单独使用 C1 模式或 C2 模式,使用 -client 或 -server 打开即可。
解释模式(Interpreted Mode)。即所有代码都解释执行,使用 -Xint 参数可以打开这个模式。
编译模式(Compiled Mode)。 此模式优先采用编译,但是无法编译时也会解释执行,使用 -Xcomp 打开这种模式。
在命令行中输入 java -version 可以看到,我机器上的虚拟机使用 Mixed Mode 运行模式。
小结
前端编译器、JIT 编译器、AOT 编译器。
前端编译器,最常见的就是我们的 javac 编译器,其将 Java 源代码编译为 Java 字节码文件。JIT 即时编译器,最常见的是 HotSpot 虚拟机中的 Client Compiler 和 Server Compiler,其将 Java 字节码编译为本地机器代码。而 AOT 编译器则能将源代码直接编译为本地机器码。
编译速度:
解释执行 > AOT 编译器 > JIT 编译器。
编译质量:
JIT 编译器 > AOT 编译器 > 解释执行。
而在 JVM 中,通过这几种不同方式的配合,使得 JVM 的编译质量和运行速度达到最优的状态。
参考链接: