首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >带你从零理解 JIT

带你从零理解 JIT

作者头像
灬沙师弟
发布2025-11-12 13:45:04
发布2025-11-12 13:45:04
1950
举报
文章被收录于专栏:Java面试教程Java面试教程

1. 什么是 JIT?

阶段

执行方式

速度

代表语言

纯解释

字节码 → 解释器逐条执行

早期 BASIC

静态编译

源码 → 机器码(提前)

C/C++

Java 的混合模型

字节码 → 解释 + JIT 编译

最终≈C

Java/Kotlin/Scala

JIT = Just-In-Time Compiler “在运行期,把热点字节码动态编译成机器码,并缓存起来,下次直接跳机器码。”


2. 为什么需要 JIT?

  1. 平台无关.class 仍是字节码,一次编译到处运行。
  2. 峰值性能:热点代码(Hot Spot)被编译后,速度可与静态编译语言比肩。
  3. 自适应优化:运行时收集 profiling 信息,做** speculative 优化**(内联、循环展开、向量化、逃逸分析……),比静态编译器更了解“这次运行”的数据。

3. HotSpot 的 JIT 家族

编译器

触发阈值

优化程度

备注

C1(Client)

1 000 次

简单优化

启动快,适合 GUI

C2(Server)

10 000 次

激进优化

峰值性能,后台线程

Graal(JDK 17+)

可配置

最高

用 Java 写的新 JIT,实验/生产均可

默认开启分层编译(Tiered):先 C1 快速编译,热度继续涨 → C2 再编译一次。


4. 肉眼观测 JIT 的 3 把瑞士军刀

参数

作用

-XX:+PrintCompilation

每发生一次 JIT 编译就打印一行

-XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining

看谁被内联,谁被“踢出去”

-XX:+PrintAssembly(需要 hsdis 插件)

直接输出机器码,终极杀器


5. 一段 30 行代码,让 JIT 现形

代码思路:

  1. 写一个“累加”方法,纯计算,无 I/O。
  2. 先“预热” 50 000 次(触发 JIT)。
  3. 再正式跑 50 000 次,统计耗时。
  4. 通过开关 JIT,对比速度差 10× 以上。
代码语言:javascript
复制
public class JITDemo {
    // 纯计算:高斯求和公式,故意写成循环方便 JIT 优化
    private static long sum(int n) {
        long s = 0;
        for (int i = 1; i <= n; i++) {
            s += i;
        }
        return s;
    }

    public static void main(String[] args) {
        int n = 1000;
        int warmup  = 50_000;
        int measure = 50_000;

        // 1. 预热阶段:触发 JIT
        for (int i = 0; i < warmup; i++) {
            sum(n);
        }

        // 2. 正式测量
        long t0 = System.nanoTime();
        for (int i = 0; i < measure; i++) {
            sum(n);
        }
        long t1 = System.nanoTime();

        System.out.printf("sum(1..%d) called %,d times, average %.3f ns/call%n",
                          n, measure, (t1 - t0) * 1.0 / measure);
    }
}

6. 实验:把 JIT 关掉再跑

命令

结果(i7-12700H, JDK 21)

java JITDemo(默认开启 JIT)

7 ns/call

java -Djava.compiler=NONE JITDemo(纯解释)

220 ns/call

java -XX:+PrintCompilation JITDemo

看到 sum 方法被 C1 然后 C2 编译

30 倍差距,肉眼可见!


7. 进阶:看一眼机器码

安装 hsdis(Linux 可直接 apt install hsdis-amd64)。

运行

代码语言:javascript
复制
java -XX:+UnlockDiagnosticVMOptions \
     -XX:+PrintCompilation \
     -XX:+PrintAssembly \
     -XX:CompileCommand=print,*JITDemo.sum \
     JITDemo

在输出里你能找到 add %rax, %rdx 等指令——这就是 C2 为你生成的机器码。


8. JIT 的“黑魔法”速览

优化

效果

一句话

方法内联

去掉 call 开销

把 sum 直接展开到 main 里

循环展开

减少分支

一次算 4 次加法

逃逸分析

栈上分配

对象没逃出线程,直接拆成标量

锁消除

去掉同步

发现锁只被单线程访问

向量化

SIMD

一次算 256 bit


小结

  1. Java 先解释,跑热了整段编译成机器码。
  2. 编译时带着运行时 profiling,优化比静态编译更激进。
  3. -XX:+PrintCompilation-Djava.compiler=NONE 自己玩一遍,比背十本书都深刻。

给新朋友准备了这些干货,不管是提升技术还是跳槽涨薪都用得上:

1.Java 开发宝典:涵盖 Java 基础、Spring 全家桶、中间件(RabbitMQ/Kafka 等)、数据库(MySQL/Redis)、JVM 等核心内容

2.面试题:最新八股文 + 中大厂高频题,刷完面试有底、谈薪有底气

3.项目实战:商城 / 支付中心 / SSO 等可写进简历的项目

4.系统设计:今年最新场景题(订单 / 秒杀 / IM 等),帮你搞定面试设计难点

5.简历模板:大厂高薪模板,直接套用突出优势

扫下方二维码,无套路直接领!学习有问题或需要其他资料,随时找我~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-11-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java面试教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是 JIT?
  • 2. 为什么需要 JIT?
  • 3. HotSpot 的 JIT 家族
  • 4. 肉眼观测 JIT 的 3 把瑞士军刀
  • 5. 一段 30 行代码,让 JIT 现形
  • 6. 实验:把 JIT 关掉再跑
  • 7. 进阶:看一眼机器码
  • 8. JIT 的“黑魔法”速览
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档