性能优化 - 案例篇:JIT

在这里插入图片描述


Pre

性能优化 - 理论篇:常见指标及切入点

性能优化 - 理论篇:性能优化的七类技术手段

性能优化 - 理论篇:CPU、内存、I/O诊断手段

性能优化 - 工具篇:常用的性能测试工具

性能优化 - 工具篇:基准测试 JMH

性能优化 - 案例篇:缓冲区

性能优化 - 案例篇:缓存

性能优化 - 案例篇:数据一致性

性能优化 - 案例篇:池化对象_Commons Pool 2.0通用对象池框架

性能优化 - 案例篇:大对象的优化

性能优化 - 案例篇:使用设计模式优化性能

性能优化 - 案例篇:并行计算

性能优化 - 案例篇:多线程锁的优化

性能优化 - 案例篇:CAS、乐观锁、分布式锁和无锁

性能优化 - 案例篇: 详解 BIO NIO AIO

性能优化 - 案例篇: 19 条常见的 Java 代码优化法则

性能优化 - 案例篇:JVM垃圾回收器


  1. 引言:JIT 优化的重要性与背景
  2. 方法内联:原理、配置与案例
  3. 编译层次与分层编译:C1、C2、Graal 及 profiling
  4. 逃逸分析及标量替换:栈上分配与同步消除
  5. Code Cache 管理:容量、监控与调优
  6. JITWatch 工具演示
  7. 小结
    在这里插入图片描述
    JIT 最主要的目标是把解释执行变成编译执行

1. 引言

Java 虚拟机栈的“栈帧+操作数栈”模型虽能保证跨平台,但解释执行开销巨大。JIT(Just-In-Time 编译器)正是为了解决这类热点路径上的性能瓶颈:将反复执行的字节码动态编译为本地机器码,并在运行时做多种优化,从而显著提升吞吐与响应速度。

在这里插入图片描述


2. 方法内联

  • 原理:将短小方法体直接“拷贝”到调用处,省去一次调用/返回过渡,减少栈帧创建,降低指令跳转。

  • Java 参数

    • -XX:+Inline/-XX:-Inline 启用或禁用内联。
    • -XX:CompileCommand=exclude,类名.方法名 精细排除。
  • 注解控制@ForceInline 强制内联,@DontInline 禁止内联。

  • 案例(JMH Benchmark)

    baseline    ≈0.48 ns/op
    dontInline  ≈1.93 ns/op
    exclude     ≈57.6 ns/op
    inline      ≈0.48 ns/op
    

    内联后比不内联快约 5 倍;整体 JIT 与解释执行差距可达数百倍。


3. 编译层次与分层编译

在这里插入图片描述

  • 即时编译器:HotSpot 提供 C1(客户端)和 C2(服务器),JDK10+ 可选 Graal。

  • 分层编译流程

    1. 解释执行字节码;
    2. C1 无 profiling 执行;
    3. C1 部分 profiling(方法/循环计数);
    4. C1 全 profiling;
    5. C2 优化执行。
  • 触发阈值-XX:CompileThreshold,分层编译时失效,改用动态自适应策略。

  • 后台编译:C1/C2 线程与业务线程并行,不阻塞解释执行。


4. 逃逸分析与标量替换

  • 逃逸分析:JIT 通过 -XX:+DoEscapeAnalysis(默认开启)判断对象是否“逃出”方法或线程。

    • 场景:赋值给字段/静态变量、通过 return 返回即视为逃逸。
  • 优化手段

    1. 栈上分配:对“未逃逸对象”直接在栈帧分配,减少堆分配与 GC 压力;
    2. 标量替换:将对象拆解为基本类型局部变量;
    3. 同步消除:对仅限单线程访问的 synchronized 区块可去除,需 -XX:+EliminateLocks
  • 示例

    public Object test() {
        Object obj = new Object(); // 若未逃逸,可栈上分配
        return obj;                // 返回即逃逸,不优化
    }
    

5. Code Cache 管理

  • 作用:存储 JIT 编译后的本地机器码,启动后不可自动扩容。
  • 风险:满后停止编译,退化为解释执行;过度编译还会增加 CPU 占用。
  • 调优-XX:ReservedCodeCacheSize=xxxM 增加缓存上限;可配合监控工具观察 CodeCacheUsage

6. JITWatch 工具演示

  1. 安装与日志

    -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation -XX:LogFile=jitdemo.log
    
  2. 可视化:使用 JITWatch 打开 jitdemo.log,查看内联、逃逸分析、汇编级别的编译决策。

  3. 案例:在 for 循环中对 add(a,b) 方法进行内联,观察热点路径已被替换为一段机器码。


小结

  • JIT 是 JVM 性能的关键驱动力,通过方法内联、分层编译、逃逸分析等多种策略,将解释执行转换为高效本地执行。
  • 合理调优 InlineCompileThresholdCodeCacheSize,并借助 JITWatch 等工具,可精细掌控编译效果。
  • 同时也要警惕优化副作用,如过度编译、JIT 失效导致的逆优化场景。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小工匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值