Skip to content

面试速答(先看这里)

**一句话结论:**AOT编译 ,翻译一下就是提前编译,它不像JIT一样在运行期才生成机器码,而是在编译期间就将字节码转换为机器码,这就直接省去了运行时对JVM的依赖。

60秒标准回答:

我们都知道,Java中有两种编译方法

1、javac把java代码编译成字节码,然后由Java虚拟机解释执行

2、JIT把java的字节码直接编译成机器码,然后由Java虚拟机直接运行

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**2、JIT把java的字节码直接编译成机器码,然后由Java虚拟机直接运行。
  • **要点2:**但是,JIT编译有一些比较明显的缺点也是不能忽视的:
  • **要点3:**而在如今云原生盛行的今天,应用的快速启动以及减少预热时长是非常重要的,特别是Serverless场景中,所以, 一 个新兴的编译器GraalVM就诞生了。
  • **要点4:**因为AOT编译是在编译期就生成机器代码了,所以,应用启动时就不需要编译,那么他就可以大大的减少应用的启动时间,提升系统的整体性能。
  • **要点5:**1、机器执行的时候执行的是经过编译优化的本地代码。

**记忆锚点:**Java → JIT → java → AOT → javac → native

关键取舍:

  • 可能会影响应用性能 :JIT 编译是需要进行热点代码检测、代码编译等动作的,这些都是要占用运行期的资源,所以,JIT编译过程中也可能会影响应用性能。
  • 详见: 因为AOT编译是在编译期就生成机器代码了,所以,应用启动时就不需要编译,那么他就可以大大的减少应用的启动时间,提升系统的整体性能。
  • 所以他非常适用于对启动时间敏感的场景,例如云原生应用。

易错提醒:

  • 但是,JIT编译有一些比较明显的缺点也是不能忽视的: 增加启动时间 :由于JIT编译器在程序运行时编译代码,它可能导致应用程序的启动时间较长。
  • 静态编译的局限性 一个Java程序之所以能做静态编译,需要满足一个至关重要的前提—— 封闭性假设 。

加分表达:

  • 而在如今云原生盛行的今天,应用的快速启动以及减少预热时长是非常重要的,特别是Serverless场景中,所以, 一 个新兴的编译器GraalVM就诞生了。
  • 与传统的Java的运行时编译(动态编译/jit)相比,静态编译主要有几个重要的优势: 1、机器执行的时候执行的是经过编译优化的本地代码。

追问准备:

  • 围绕「Java」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「JIT」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「java」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

我们都知道,Java中有两种编译方法:

1、javac把java代码编译成字节码,然后由Java虚拟机解释执行。

2、JIT把java的字节码直接编译成机器码,然后由Java虚拟机直接运行。

📄 ✅简单介绍一下JIT优化技术?

打开文档:✅简单介绍一下JIT优化技术?

但是,JIT编译有一些比较明显的缺点也是不能忽视的:

  1. 增加启动时间:由于JIT编译器在程序运行时编译代码,它可能导致应用程序的启动时间较长。
  2. 可能会影响应用性能:JIT编译是需要进行热点代码检测、代码编译等动作的,这些都是要占用运行期的资源,所以,JIT编译过程中也可能会影响应用性能。

而在如今云原生盛行的今天,应用的快速启动以及减少预热时长是非常重要的,特别是Serverless场景中,所以,一个新兴的编译器GraalVM就诞生了。他提出了一种新的编译方式——Ahead of Time,即AOT编译。

📄 ✅为什么云原生对应用的启动速度要求很高?

打开文档:✅为什么云原生对应用的启动速度要求很高?

AOT编译,翻译一下就是提前编译,它不像JIT一样在运行期才生成机器码,而是在编译期间就将字节码转换为机器码,这就直接省去了运行时对JVM的依赖。这是一种典型的静态编译技术。

> java 静态编译,是指将java程序的字节码在单独的离线阶段编译为汇编代码,它的输入是Java的字节码,输出是native image。

这里多说一句,很多人会误以为编译期的编译不是javac吗?其实javac只是把源代码(.java)编译成中间代码(.class),这种中间代码我们叫做字节码,而字节码并不是机器代码,无法直接执行,需要解释器进行解释执行。详见:

📄 ✅Java是编译型还是解释型?

打开文档:✅Java是编译型还是解释型?

因为AOT编译是在编译期就生成机器代码了,所以,应用启动时就不需要编译,那么他就可以大大的减少应用的启动时间,提升系统的整体性能。所以他非常适用于对启动时间敏感的场景,例如云原生应用。

image.png

扩展知识 ​

静态编译的优势 ​

与传统的Java的运行时编译(动态编译/jit)相比,静态编译主要有几个重要的优势:

1、机器执行的时候执行的是经过编译优化的本地代码。执行本地代码可以非常的高效和快速,并不需要进行解释执行和JIT编译,就可以直接执行。

2、静态编译后的可执行程序自包含了轻量级运行时支持,所以他在运行时不再需要依赖额外的JVM。

3、解决应用程序的冷启动问题。有了静态编译后的本地代码,应用程序就可以快速地启动,不再解释执行,也不再需要JIT的预热。

4、打破Java程序与本地代码之间的边界。因为编译后的代码也是本地代码,所以JNI调用的开销更低了。

静态编译的局限性 ​

封闭性假设 ​

一个Java程序之所以能做静态编译,需要满足一个至关重要的前提——封闭性假设。

什么是封闭性假设,也就是说他要求所有运行时的内容必须在编译时可见,并且可以被编译到native image中。但是Java中有很多代码是没有办法在编译期就确定的,比如反射,他就是不满足封闭性假设的。

其他的类似的违反封闭性假设的特性还有动态代理、序列化、JNI、动态类加载等等。所以,遇到这些代码的时候,就需要额外的适配来解决。带来了很多的复杂性,也给静态编译带来了一定的局限性。

平台相关性 ​

Java有一个很重要的特性就是平台无关性,但是随着静态编译的盛行,这个说法已经并不一定就成立了。

静态编译以后的代码程序,其实就是平台相关的了。

📄 ✅Java一定就是平台无关的吗?

打开文档:✅Java一定就是平台无关的吗?