原文链接:https://blog.csdn.net/tjiyu/article/details/53748965

 Java程序代码需要编译后才能在虚拟机中运行,编译涉及到非常多的知识层面:编译原理、语言规范、虚拟机规范、本地机器码优化等;了解编译过程有利于了解整个Java运行机制,不仅可以使得我们编写出更优秀的代码,而且还可以使得在JVM调优时更得心应手。

       下面我们先来看下Java体系中的三种编译方式:前端编译、即时编译(JIT编译)、静态提前编译(AOT编译),先来了解它们各有什么优点和缺点,再来看看主流的前端编译+JIT编译方式的运作过程。

1、前端编译

       把Java源码文件(.java)编译成Class文件(.class)的过程;

       也即把满足Java语言规范的程序转化为满足JVM规范所要求格式的功能;

优点:

这阶段的优化是指程序编码方面的;

许多Java语法新特性("语法糖":泛型、内部类等等),是靠前端编译器实现的,而不是依赖虚拟机;

编译成的Class文件可以直接给JVM解释器解释执行,省去编译时间,加快启动速度;

缺点:

对代码运行效率几乎没有任何优化措施;

解释执行效率较低,所以需要结合下面的JIT编译;    

前端编译器:Oracle javac、Eclipse JDT中的增量式编译器(ECJ)等;

2、后端编译/即时(JIT)编译

      通过Java虚拟机(JVM)内置的即时编译器(Just In Time Compiler,JIT编译器);在运行时把Class文件字节码编译成本地机器码的过程;            

优点:

通过在运行时收集监控信息,把"热点代码"(Hot Spot Code)编译成与本地平台相关的机器码,并进行各种层次的优化;

可以大大提高执行效率;

缺点:

收集监控信息影响程序运行;

编译过程占用程序运行时间(如使得启动速度变慢);

编译机器码占用内存;

JIT编译器:HotSpot虚拟机的C1、C2编译器等;

 

另外,JIT编译速度及编译结果的优劣,是衡量一个JVM性能的很重要指标;

所以对程序运行性能优化集中到这个阶段;

也就是说可以对这个阶段进行JVM调优;

3、静态提前编译(Ahead Of Time,AOT编译)

       程序运行前,直接把Java源码文件(.java)编译成本地机器码的过程;

优点:

编译不占用运行时间,可以做一些较耗时的优化,并可加快程序启动;

把编译的本地机器码保存磁盘,不占用内存,并可多次使用;

缺点:

因为Java语言的动态性(如反射)带来了额外的复杂性,影响了静态编译代码的质量;

一般静态编译不如JIT编译的质量,这种方式用得比较少;

静态提前编译器(AOT编译器):JAOTC、GCJ、Excelsior JET、ART (Android Runtime)等;

 

关于ART (Android Runtime)模式:ART虽然主要通过AOT编译支持Java的运行,但仍然带有解释器。

更多ART请参考:《ART没有了Java虚拟机,能支持的了JNI吗?比如Java和C++互调用,还有ART不用解释器了那有没有可能放弃Java呢?

《Android运行时ART简要介绍和学习计划》

更多AOT请参考:《Java中有类似于NGen的工具(AOT编译器)吗?

4、前端编译+JIT编译

到这里,我们知道目前Java体系中主要还是采用前端编译+JIT编译的方式,如JDK中的HotSpot虚拟机。

前端编译+JIT编译方式的运作过程大体如下:

1、首先通过前端编译把符合Java语言规范的程序代码转化为满足JVM规范所要求Class格式;

2、然后程序启动时Class格式文件发挥作用,解释执行,省去编译时间,加快启动速度;

3、针对Class解释执行效率低的问题,在运行中收集性能监控信息,得知"热点代码";

4、JIT逐渐发挥作用,把越来越多的热点代码"编译优化成本地代码,提高执行效率;

 

      后面我们将分别去了解:前端编译--把Java源码文件编译成Class文件的过程、Class文件的结构、以及JIT编译--在运行时把Class文件字节码编译成本地机器码的过程……

 

【参考资料】

1、《The Java Virtual Machine Specification》Java SE 8 Edition:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

2、《深入理解Java虚拟机:JVM高级特性与最佳实践》第二版

3、实时Java,第2部分: 比较编译技术--本地 Java 代码的静态编译和动态编译中的问题:www.ibm.com/developerworks/cn/java/j-rtj2/

4、很多文章都提到JVM对class文件的编译,那么编译后的文件是在内存里还是在哪?怎么查看?:https://www.zhihu.com/question/52487484/answer/130785455

   5、Java中有类似于NGen的工具(AOT编译器)吗?:https://www.zhihu.com/question/29852046/answer/45917208

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐