Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/java/basis/java-basic-questions-01.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ JRE 是运行已编译 Java 程序所需的环境,主要包含以下两个部

> 🌈 拓展阅读:
>
> - [基本功 | Java 即时编译器原理解析及实践 - 美团技术团队](https://tech.meituan.com/2020/10/22/java-jit-practice-in-meituan.html)
> - [基本功 | Java 即时编译器原理解析及实践 - 美团技术团队](https://mp.weixin.qq.com/s/7PH8o1tbjLsM4-nOnjbwLw)
> - [基于静态编译构建微服务应用 - 阿里巴巴中间件](https://mp.weixin.qq.com/s/4haTyXUmh8m-dBQaEzwDJw)

![Java程序转变为机器代码的过程](https://oss.javaguide.cn/github/javaguide/java/basis/java-code-to-machine-code-with-jit.png)
Expand Down Expand Up @@ -125,17 +125,17 @@ JDK、JRE、JVM、JIT 这四者的关系如下图所示。

> 为了改善解释语言的效率而发展出的[即时编译](https://zh.wikipedia.org/wiki/即時編譯)技术,已经缩小了这两种语言间的差距。这种技术混合了编译语言与解释型语言的优点,它像编译语言一样,先把程序源代码编译成[字节码](https://zh.wikipedia.org/wiki/字节码)。到执行期时,再将字节码直译,之后执行。[Java](https://zh.wikipedia.org/wiki/Java)与[LLVM](https://zh.wikipedia.org/wiki/LLVM)是这种技术的代表产物。
>
> 相关阅读:[基本功 | Java 即时编译器原理解析及实践](https://tech.meituan.com/2020/10/22/java-jit-practice-in-meituan.html)
> 相关阅读:[基本功 | Java 即时编译器原理解析及实践](https://mp.weixin.qq.com/s/7PH8o1tbjLsM4-nOnjbwLw)

**为什么说 Java 语言“编译与解释并存”?**

这是因为常见的 Java 实现同时使用编译和解释技术:Java 源码先由编译器生成字节码(`.class` 文件),字节码可由 JVM 解释执行,也可在运行时由 JIT 编译为机器码。字节码并非必须由解释器执行,具体执行策略由 JVM 实现决定。

### AOT 有什么优点?为什么不全部使用 AOT 呢?

JDK 9 曾通过 JEP 295 引入实验性的 **AOT(Ahead of Time Compilation)** 工具 `jaotc`,但该工具已在 JDK 17 中移除。因此,JDK 17 及之后的标准 JDK 不再包含这套内置 AOT 编译器;下文讨论的是一般意义上的 AOT,以及 GraalVM Native Image 等独立工具链。和 JIT 不同,AOT 会在程序执行前将代码编译为机器码,能够减少运行时预热开销并改善启动速度,但具体的内存占用、峰值性能和适用场景取决于所使用的 AOT 实现与应用负载。
JDK 9 曾通过 JEP 295 引入实验性的 AOT(Ahead of Time Compilation)工具 `jaotc`,但该工具已在 JDK 17 中移除。因此,JDK 17 及之后的标准 JDK 不再包含这套内置 AOT 编译器;下文讨论的是一般意义上的 AOT,以及 GraalVM Native Image 等独立工具链(Native Image 是 GraalVM 提供的一项 AOT 技术,后文会进一步介绍 GraalVM)。和 JIT 不同,AOT 会在程序执行前将代码编译为机器码,能够减少运行时预热开销并改善启动速度,但具体的内存占用、峰值性能和适用场景取决于所使用的 AOT 实现与应用负载。

下面的对比以常见的 HotSpot JIT 和 GraalVM Native Image 为例。不同 AOT 工具的实现方式并不完全相同,实际表现还会受到构建参数、PGO(Profile-Guided Optimization,基于性能数据的优化)和应用负载影响
下面的对比以常见的 HotSpot JIT 和 GraalVM Native Image 为例。不同 AOT 工具的实现方式并不完全相同,实际表现还会受到构建参数、应用负载,以及是否使用 PGO(Profile-Guided Optimization,即利用程序实际运行时收集的性能信息辅助优化)等因素影响

| 对比维度 | JIT(即时编译) | AOT(提前编译) |
| ---------------- | ---------------------------------------- | -------------------------------------------------- |
Expand All @@ -149,7 +149,7 @@ JDK 9 曾通过 JEP 295 引入实验性的 **AOT(Ahead of Time Compilation)*

<img src="https://oss.javaguide.cn/github/javaguide/java/basis/jit-vs-aot.png" alt="JIT vs AOT" style="zoom: 25%;" />

AOT 的优势主要体现在启动速度和运行时内存占用,比较适合冷启动频繁、实例生命周期较短或者需要快速扩容的应用。JIT 能根据程序运行时收集到的信息优化热点代码,长时间运行的服务通常更容易发挥这方面的优势。二者的吞吐量和延迟表现不能只由编译方式直接下结论,还需要结合具体工具链和实际负载测试。
AOT 的优势主要体现在启动速度和运行时内存占用,比较适合冷启动频繁、实例生命周期较短或者需要快速扩容的应用。JIT 则能根据程序运行时收集到的信息优化热点代码,长时间运行的服务通常更容易发挥这方面的优势。二者的吞吐量和延迟表现不能只由编译方式直接下结论,还需要结合具体工具链和实际负载测试。

提到 AOT 就不得不提 [GraalVM](https://www.graalvm.org/) 了!GraalVM 是一种高性能的 JDK(完整的 JDK 发行版本),它可以运行 Java 和其他 JVM 语言,以及 JavaScript、Python 等非 JVM 语言。 GraalVM 不仅能提供 AOT 编译,还能提供 JIT 编译。感兴趣的同学,可以去看看 GraalVM 的官方文档:<https://www.graalvm.org/latest/docs/>。如果觉得官方文档看着比较难理解的话,也可以找一些文章来看看,比如:

Expand Down