Java的编译模式
2025-8-20
| 2025-8-20
字数 1502阅读时长 4 分钟
type
status
date
slug
summary
tags
category
icon
password

Java的编译模式

我们都知道java程序运行前需要经过javac编译成.class的字节码文件,然后jvm再将字节码文件转换成平台对应的本地机器码执行。
在将字节码转换成平台对应机器码的这一步,分别有几种不同的方式,他们都各有各的特点。
  • 解释执行(Interpreter) Java是解释型语言每次运行的时候都会通过解释器逐句解释字节码翻译成本地机器码然后运行,运行效率对比编译型(C、C++、Go、Rust)语言会低很多。
  • 即时编译(JIT, Just-In-Time Compilation) 有时候在执行的过程中会重复执行多次的代码被称为热点代码,JIT编译对这部分代码会进行优化,当代码被统计执行的次数达到了热点代码的阈值,那么JVM就会将这部分代码的平台机器码直接缓存,下次运行的时候就直接运行,而不需要重复解释再执行。并且除了热点代码的优化,JIT也支持一些动态优化。
  • 提前编译(AOT, Ahead-Of-Time Compilation) 在程序运行前就提前将所有代码都编程成本地的机器码,方便直接运行。但是对于一些Java的动态特性就无法支持AOT编译,比如反射、动态代理、动态加载等等。
在JVM中默认的编译模式为:解释执行+JIT的混合模式,先解释执行,对于热点代码使用JIT编译
 
以下为ai对JIT动态优化的总结: JIT 不仅仅是缓存热点代码的机器码,它的核心优势在于 动态优化,通过分析 运行时的程序行为,针对性地生成 更高效的机器码。这才是为什么 JIT 在 长期运行 时,能表现出 更好的性能

关键总结:

  1. JIT 的核心:动态优化
      • 缓存热点代码:将频繁调用的方法编译成机器码,避免重复解释执行。
      • 根据运行时信息做优化:通过对代码执行的实际情况分析(比如分支预测、方法内联、循环展开等),生成更高效的机器码。
  1. 优化示例
      • 分支优化:如果某个条件分支经常是某一边,JIT 会调整机器码让那个分支直接走高效路径,避免每次都判断。
      • 方法内联:小方法会直接嵌入调用点,减少方法调用的开销。
      • 逃逸分析:如果某个对象不会被外部引用,JIT 会避免堆分配,直接在栈上分配,减少 GC 压力。
  1. JIT 和 AOT 的不同
      • AOT 在编译时做优化,但没有运行时信息,缺乏像 JIT 那样的 灵活性和针对性,所以在 长时间运行的应用中,JIT 能提供更优的性能。

所以,JIT 不仅是加速“预编译”,它是智能的,能不断根据程序的实际运行情况,调整和优化机器码,让应用 更加高效
Java 编译/执行方式全维度对比表
维度
解释执行 (Interpreter)
JIT 编译 (Just-In-Time)
AOT 编译 (Ahead-Of-Time)
启动速度
最快 — 逐条解释执行,无预编译开销
中等 — 先解释,待热点代码触发后进行 JIT 编译
最快 — 执行前已编译为本地机器码,无预热延迟 (JavaGuide, 维基百科)
执行效率
最低 — 每次解释字节码,效率受限
最高 — 利用运行时数据进行深度优化(内联、逃逸分析、分支预测等)
中高 — 直接执行本地机器码,但缺少 JIT 的动态优化能力 (JavaGuide, 博客园)
运行时内存占用
最低 — 无机器码缓存,仅需加载字节码
较高 — 除字节码,还需缓存 JIT 生成的机器码(Code Cache)
低于 JIT — 不需 JIT 缓存,只加载 AOT 机器码和少量运行支持数据
磁盘体积
最小 — 仅 .class/.jar 文件
中等 — 字节码为主,运行时生成机器码不计入磁盘
最大 — 包含完整机器码、元数据、反射/GC 支持等(如 GraalVM Native Image) (JavaGuide, 博客园)
优化能力
极低 — 只是直译执行
最强 — 根据运行时行为进行动态优化
中等 — 编译期优化但缺乏动态适配
动态特性支持
完整支持 — 解释器可处理所有 Java 特性
完整支持 — JIT 支持反射、动态代理、类加载
受限 — 动态特性(反射、CGLIB 动态代理、类加载等)需额外配置或不支持 (JavaGuide, 博客园)
跨平台性
极好 — 字节码可在任意 JVM 上运行
极好 — 通过 JVM 跨平台执行
差 — 可执行文件通常绑定特定平台/架构
适用场景
调试、小脚本、快速测试
长生命周期服务、大规模后端、高性能要求场景
云原生、CLI、微服务、Serverless、启动敏感应用
主要缺点
性能差、无缓存优化
启动慢(预热)、占内存、较复杂
打包大、构建慢、不支持动态特性、跨平台差
举例
启动时配置 -Xint 强制解释执行
HotSpot VM 默认 C1/C2 分层 JIT 模式
GraalVM Native Image、Android ART AOT 模式 (JavaGuide, 博客园)
参考:JavaGuideJavaGuideJava基础常见面试题总结(上)
 
  • Java
  • 八股
  • Git常用操作高并发场景下数据库与缓存的一致性
    Loading...