ava程序代码需要编译后才能在虚拟机中运行,编译涉及到非常多的知识层面:编译原理、语言规范、虚拟机规范、本地机器码优化等;了解编译过程有利于了解整个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编译分类:前端编译和后端编译相关推荐

  1. java后台转前端_从后端开发转职前端开发,我都经历了些什么?

    原标题:从后端开发转职前端开发,我都经历了些什么? 从前端转行后端 从后端开发转职到前端开发真的不容易. 特别是当你已经习惯了后端开发的工作模式,习惯了构建数据结构,编写类似于测试驱动开发的测试,习惯 ...

  2. 深入理解Java虚拟机(周志明第三版)- 第十一章:后端编译与优化

    系列文章目录 第一章: 走近Java 第二章: Java内存区域与内存溢出异常 第三章: Java垃圾收集器与内存分配策略 从计算机程序出现的第一天起,对效率的追逐就是程序员天生的坚定信仰,这个过程犹 ...

  3. linux系统软件包分类,Linux软件包管理和编译安装

    软件包介绍 开源软件最初只提供了.tar.gz的打包的源码文件,用户必须自已编译每个想在GNU/Linux上运行的软件.用户急需系统能提供一种更加便利的方法来管理这些软件,当Debian诞生时,这样一 ...

  4. 后端编译与优化(JIT,即时编译器)

    目录 解释器与编译器 编译对象与触发条件 编译过程 查看及分析即时编译结果 目前主流的两款商用Java虚拟机(HotSpot.OpenJ9)里,Java程序最初都是通过解释器 (Interpreter ...

  5. java安全(二):JDBC|sql注入|预编译

    给个关注?宝儿! 给个关注?宝儿! 给个关注?宝儿! 关注公众号:b1gpig信息安全,文章推送不错过 1 JDBC基础 JDBC(Java Database Connectivity)是Java提供 ...

  6. java调用clang编译的so_写Java这么久,JDK源码编译过没?编译JDK源码踩坑纪实

    好奇害死羊 很多小伙伴们做Java开发,天天写Java代码,肯定离不开Java基础环境:JDK,毕竟我们写好的Java代码也是跑在JVM虚拟机上. 一般来说,我们学Java之前,第一步就是安装JDK环 ...

  7. 理解java虚拟机工作后了解吗,【深入理解JAVA虚拟机】第4部分.程序编译与代码优化.2.运行期优化。这章提到的具体的优化技术,应该对以后做性能工作会有帮助。...

    1.概述 Java程序最初是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为"热点代码"(Hot Spot C ...

  8. java 0000 0001 0002 000a 000b_Java代码编译后的class文件

    还是熟悉的味道,还是最简单的代码. // Hello.java public class Hello { public static void main(String[] args) { System ...

  9. java强制编译通过_强制java使用用户输入作为消息进行编译错误

    我不知道在Java中是否可行: 我想从用户(从System.in)获得输入,然后使用该输入引发编译错误. 我的意思是,如果用户输入了文本" HELLO",则程序应引发编译错误:编译 ...

最新文章

  1. 在中国,程序员这行能干一辈子吗?
  2. python怎么安装pandas模块-如何优雅的安装Python的pandas?
  3. weex的实践踩坑日常(一)
  4. “Content type ‘application/x-www-form-urlencoded;charset=UTF-8‘ not supported“解决方法
  5. Python核心场景自动化测试项目实战(二)
  6. 华为鸿蒙5g售价,华为首款5G手机售价公布,余承东透露鸿蒙将用于连接家庭设备...
  7. Silverlight Quick Starts翻译(二):第一章 创建一个Silverlight工程
  8. 第六章 函数逼近-强化学习理论学习与代码实现(强化学习导论第二版)
  9. [Buzz Today]2012.05.10
  10. c语言yuv图片cb,YUV格式图像基础
  11. 80端口和443端口的作用
  12. 怎么爬取全量企业工商数据(思路)
  13. 移位和循环移位指令 shl, shr sal, sar, sol, sor, scl, scr, shld, shrd
  14. SQL2005数据库备份如何还原到SQL2000数据库中
  15. 每日一道 LeetCode (4):罗马数字转整数
  16. 仿射变换(Affine Transformation)原理及应用(1)
  17. 《张宇考研数学基础30讲》思维导图-第2讲 数列极限
  18. Go语言类库-reflect(反射)
  19. GEE:GEE平台怎么提高用户内存限制
  20. nvidia-driver-460防止驱动更新

热门文章

  1. 【效率】如何有效提问
  2. nyoj983 首尾相连数组的最大子数组和
  3. windows time 服务无法启动 错误1058 解决方法
  4. lighttpd缓存配置
  5. 关系竞争 :今目标可能成为个一个的企业社交网络
  6. linux c 实现函数 trim 除去字符串首尾空格
  7. jenkins 反序列化漏洞 cve-2017-1000353
  8. linux cmake 交叉编译配置 简介
  9. linux lsof 已打开的文件列表
  10. Binutils工具集 GCC工具集介绍