问题

怎么看静态类型语言(java,flutter/dart,swift)纷纷往aot&jit双模式发展?

回答
我来给你说说,为啥像 Java、Flutter/Dart、Swift 这种曾经专攻某个领域的静态类型语言,现在都纷纷往 AOT(AheadofTime)和 JIT(JustinTime)双模模式“靠拢”的现象,这背后其实是技术发展和开发者需求在博弈的结果。

先来拆解一下 AOT 和 JIT 是啥意思:

AOT (AheadofTime) 编译: 顾名思义,就是“预先编译”。在程序运行之前,就把源代码直接转换成机器码。这就像你在考试前就把知识点背得滚瓜烂熟,考试时直接套用,速度自然飞快。
优点: 启动快、执行效率高、通常内存占用也更低,因为没有运行时编译的开销。
缺点: 编译时间长,尤其对于大型项目;调试起来可能不如 JIT 灵活。
JIT (JustinTime) 编译: 意思是“即时编译”。程序运行时,一部分代码(通常是热点代码,也就是经常被执行的部分)才会被动态地编译成机器码。这就像你在学习过程中,遇到不懂的地方,现查现用,能更好地适应现场情况。
优点: 启动速度相对较快(因为不是一开始就全编译),调试方便(可以在运行时动态调整),能够根据实际运行情况进行优化。
缺点: 第一次执行某些代码时会有编译延迟,如果编译器不够智能,优化效果可能不如 AOT。

为什么会出现这种“双模”趋势?

这背后其实是为了解决各自语言在不同应用场景下的痛点,实现“鱼与熊掌兼得”。

1. Java 的演进:从纯粹的 JIT 到拥抱 AOT

Java 最初的设计理念: “一次编写,到处运行”(Write Once, Run Anywhere)。为了实现这个目标,Java 选择了字节码(Bytecode)和 JVM(Java Virtual Machine)。Java 源代码被编译成字节码,然后在 JVM 上运行。JVM 内部有一个 JIT 编译器,在程序运行时将常用的字节码编译成机器码,从而提高性能。
JIT 的优势: 保证了跨平台性,也提供了不错的性能。
JIT 的瓶颈:
启动性能: JIT 需要时间来“预热”和编译代码,尤其是在程序启动初期,性能会受到影响,也就是所谓的“冷启动”问题。
内存占用: JVM 本身需要占用一部分内存,JIT 编译过程也需要额外的内存。
运行时优化限制: 虽然 JIT 在运行时可以根据实际情况进行优化,但它仍然受限于“运行时”的限制,很多在编译时就能确定的优化无法做到。
AOT 的引入(GraalVM Native Image): 为了解决 Java 的这些痛点,特别是针对云原生、微服务、命令行工具等需要快速启动、低内存占用的场景,Java 生态引入了 GraalVM Native Image。GraalVM 是一个高性能的 JDK 发行版,它允许将 Java 应用 AOT 编译成独立的本地可执行文件。
GraalVM Native Image 的优势: 极大地提升了启动速度,显著降低了内存占用,并且可以直接生成原生二进制文件,无需 JVM。这使得 Java 在一些传统上不适合它的场景(如 CLI 工具、Serverless 函数)中也变得可行。
双模带来的好处: 开发者现在可以根据项目需求选择 AOT 或 JIT。对于需要快速响应的场景,可以选择 AOT;对于需要灵活调试、长期运行且对启动速度要求不那么极致的服务,仍然可以使用传统的 JIT 模式。

2. Flutter/Dart:从“主打”JIT 到“全面支持”AOT

Dart 的设计: Dart 在设计之初就考虑到了高效的 UI 开发和跨平台能力。它一开始就支持 JIT 编译(用于开发环境,实现热重载)和 AOT 编译(用于发布环境,获得高性能)。
JIT 在 Flutter 中的作用: Flutter 的“热重载”(Hot Reload)功能,正是依赖于 Dart 的 JIT 模式。在开发过程中,开发者可以快速看到代码修改的效果,而无需重新编译整个应用,这极大地提升了开发效率。
AOT 在 Flutter 中的作用: 当 Flutter 应用发布到生产环境时,Dart 会被 AOT 编译成 ARM 或 x64 机器码。这使得 Flutter 应用拥有了接近原生应用的性能,启动速度快,运行流畅。
为什么说 Flutter/Dart “纷纷往 AOT&JIT 双模式发展”? 事实上,Dart 一开始就设计了双模式。但之所以说它“发展”到双模式,是因为 Flutter 的成功极大地推广了 Dart 的 AOT 编译能力。过去,Dart 主要用于 Web 开发,JIT 更为常见。而 Flutter 的出现,让 Dart 在移动端获得了巨大的成功,也让 AOT 编译在 Dart 生态中变得越来越重要和成熟。可以说,Flutter 驱动了 Dart AOT 编译体系的完善和普及。
双模的协同: 开发者可以在开发时享受 JIT 的热重载,在发布时获得 AOT 的高性能。这种模式完美契合了快速迭代和高性能发布的双重需求。

3. Swift:从 AOT 到拥抱 JIT(Swift REPL/Interactive)

Swift 最初的设计理念: Swift 是一门现代的、安全的、高性能的编程语言,目标是取代 ObjectiveC,成为 Apple 生态(iOS, macOS, watchOS, tvOS)的主要开发语言。它从一开始就选择了 AOT 编译,以获得最佳的运行时性能和更小的应用体积。
Swift 的 AOT 优势: 编译到机器码,性能出色,语法糖和安全特性可以在编译时得到检查,减少运行时错误。
JIT 的引入(Swift REPL): 尽管 Swift 主要使用 AOT,但为了提高开发和学习的便利性,Apple 也引入了 Swift REPL(ReadEvalPrint Loop),也就是交互式编程环境。Swift REPL 实际上是利用了 JIT 的原理,允许开发者在命令行中输入 Swift 代码,然后立即执行并看到结果。
REPL 的作用: 极大地便利了开发者对 Swift 语言特性、API 的探索和实验,无需编写完整的项目就可以快速验证想法。
为什么说 Swift 往 AOT&JIT 双模式发展? 严格来说,Swift 的核心仍然是 AOT。但“发展”到双模式,更多体现在 “以 AOT 为主,但 JIT 的能力(如 REPL)在开发者工具链中变得越来越重要和不可或缺”。这种趋势是让语言在保持核心高性能优势的同时,也提供更便捷的开发和学习体验。Swift 的一些运行时特性(如动态性)也在不断演进,这在某种程度上也带有 JIT 的灵活性影子。

总结一下这种趋势背后的驱动力:

对性能的极致追求: 无论前端还是后端,开发者总是希望应用启动更快、响应更及时、资源占用更少。AOT 编译在这方面有天然优势。
提升开发效率: JIT 模式(特别是热重载)能极大地缩短开发周期,提高开发者的幸福感。
适应多样化的应用场景:
云原生/微服务/Serverless: 需要极快的启动速度和低内存占用,AOT 成为首选。
移动端/桌面端应用: 需要高性能、流畅的用户体验,AOT 是基础。
脚本/工具/原型开发: 快速迭代和交互式编程非常重要,JIT 更合适。
语言生态的成熟和技术的进步: 编译器技术、运行时环境都在不断进步,使得同时支持 AOT 和 JIT 变得更加可行和高效。例如,GraalVM 的出现就是技术进步的一个体现。
竞争与学习: 不同语言生态之间会相互借鉴,当一种模式在某个场景下表现出色时,其他语言也会考虑引入类似的能力来弥补自身的短板。

所以,我们看到这些曾经“专一”的静态类型语言,都在努力打破自身的边界,融合 AOT 和 JIT 的优点,以应对日益复杂和多样化的开发需求,提供更全面、更优秀的开发者体验和产品性能。这是一种技术发展的必然,也是为了更好地服务开发者和用户。

网友意见

user avatar

原因之一是技术发展更加细化了,需要去更多方向上发展,做更好的组合,来榨取更多价值

理论上说,java这种静态类型一开始就可以很适合AOT模式的,(GC之类的问题其实并不必须VM,也可以VEE,像Go这样),只要不嫌麻烦在各种平台上搞对应编译器(或者通过其他代码中转,如java->C),但因为某些原因并没有直接做成这样,当年微软的VJ似乎就这么干,然后被起诉了。。。

直接解释执行性能是个问题,如果不AOT,那么就JIT,然后大家发现JIT也就是“慢热”了一点,实际效果可能比AOT还好,因为JIT可以做到AOT做不到的一些动态优化,于是干脆就解释+JIT这个架构搞定,综合性价比最高

不过随着应用和需求的发展,JIT的一些弱点(比如上面说的慢热之类)也显现了,这时候就引入AOT来补足,也是挺自然的事情

但并非所有解释+JIT的架构都可以引入AOT来解决一些问题,例如你提到的pypy,基本就没有AOT的价值,这很大程度是Python语言本身特性决定的

反过来说,题主提的C++、Go这种一般以“AOT”形式实现的语言,难道就不能再进一步引入JIT来优化性能么,其实是可以的,说不定将来也会是一个趋势

user avatar

所谓的十年风水轮流转呗。

早期的计算机由于性能真的不行,所以需要程序能尽可能的吃尽计算机的性能,运行效率才能被人接受。所以那时候的语言都专注于运行效率,用得多的基本都是 AoT 编译型语言。

在摩尔定律还适用的年代,计算机的性能不断提升,内存也越来越大,再加上 Ruby 的出现,让人开始关注开发效率,运行效率反而被一定程度地忽视,反正我写的程序这一代计算机跑不动,下一代就能跑动了。而开发效率并不会因为CPU性能提升而成正比地提升,所以这个阶段比较流行的是那些关注开发效率的解释型语言。

现在摩尔定律已经不适用了,CPU运算速度很难再往上提。在各种新兴语言都已经让开发人员敲得足够爽的情况下,关注点自然又会回归到运行效率,但是开发效率和语言的表现力又不想放弃,所以很多解释型语言开始搞 JIT 编译器,而在这个阶段的全新语言也会考虑 AoT,只要工具链做的够好,AoT 在开发效率上也一样高效。

说白了,计算机领域就是个在贪婪和怠惰这两种原罪的相互作用下不断发展的领域。贪婪是技术革新的第一推动力,而怠惰指明了革新的方向。

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有