JVM编译器

一、编译器

1. 前端编译器(javac)

.java.class 字节码属于 编译期 ,只做语法解析、泛型擦除、语法糖解耦,不做运行期优化

2. 后端即时编译器(JIT)

运行时把 字节码 → 机器码 属于 JVM 执行子系统 ,带运行期优化(逃逸分析、循环优化、锁消除等)。

二、JVM内置三大编译器

1. 解释器(Interpreter)

逐行解释执行字节码,不编译成机器码。

  • 启动快、省内存
  • 循环多、热点代码性能差

2. C1 编译器(Client 客户端编译器)

又叫 简单即时编译器

  • 编译速度快、优化保守
  • 适合桌面客户端、启动快优先
  • 做简单优化:常量折叠、方法内联

3. C2 编译器(Server 服务端编译器)

高性能编译器,面试重点

  • 编译稍慢,但优化极强
  • 服务端默认
  • 支持高阶优化:
    • 逃逸分析
    • 标量替换、栈上分配
    • 锁消除、锁粗化
    • 循环展开、循环无关外提

三、分层编译(JDK 默认)

解释器 + C1 + C2 配合工作

  1. 刚开始:解释器先跑,启动快
  2. 代码跑多了成为热点代码 → 交给 C1 编译
  3. 继续高频执行 → 升级 C2 深度优化

不用等全量编译,兼顾启动速度 + 运行高性能

四、热点代码是什么

触发 JIT 编译的两类代码:

  1. 被多次调用的方法
  2. 被多次循环执行的循环体

计数器 统计热度,阈值到了就触发 JIT 编译优化。

五、JIT 编译器核心优化(必背)

1. 方法内联

(1) 什么是方法内联

小方法的方法体代码 ,直接复制粘贴 到调用处,消除方法调用本身,不再走:调用 → 栈帧创建 → 参数传递 → 返回 → 栈帧销毁 这套流程。

通俗说:把小方法拆了,代码直接嵌进去用

(2) 解决问题

  • 减少方法调用栈帧开销
  • 减少参数压栈、跳转、返回的性能损耗
  • 给后续其他优化创造前提(逃逸分析、标量替换、锁消除都依赖内联)

(3) 内联带来的连锁优化

方法内联之后,JVM 才能做:

  • 逃逸分析
  • 标量替换
  • 栈上分配
  • 锁消除
  • 常量传播、死代码消除

很多高级优化前提就是先做方法内联

2. 逃逸分析

(1) 作用

分析一个对象的作用域 ,判断对象是否逃逸出当前方法、当前线程

  • 不逃逸:对象只在方法内部使用
  • 逃逸:对象被返回、赋值给成员变量、被其他线程引用

(2) 未逃逸对象的3大核心优化

  • 栈上分配:对象没有逃逸,直接分配在栈上,方法结束自动销毁,不走 GC,极大减轻堆压力。
  • 标量替换:把对象拆解成一个个基本变量,不再创建整体对象,节省内存。
  • 同步消除:对象没有多线程共享逃逸,自动把 synchronized 锁消除,提升性能。

(3) 发生对象逃逸的情况

  • 对象作为方法返回值返回
  • 对象赋值给成员变量、静态变量
  • 对象传入多线程、线程池中使用
  • 对象被其他类引用持有

3. 锁消除

(1) 定义

某个锁对象没有逃逸 ,只在当前方法、当前线程内部使用,不存在多线程竞争,直接把 synchronized 锁给删掉,消除加锁解锁开销。

(2) 原理

  • 逃逸分析:判断锁对象是否只被当前线程访问,不对外逃逸;
  • 无共享、无竞争 → 虚拟机判定锁毫无意义
  • JIT 编译时直接抹掉锁逻辑,变成普通代码执行。

4. 锁粗化

(1) 什么是锁粗化

如果连续多次对同一个对象反复加锁、解锁 ,JIT 会把多段小锁合并成一把大锁,减少频繁加解锁的开销。

(2) 触发场景

同一个锁对象,在连续代码块里频繁加解锁

  • 循环里反复加锁
  • 连续调用同一个同步方法

(3) 和锁消除区别

  • 锁消除:根本没竞争,直接把锁删掉
  • 锁粗化 :锁必须保留,只是把多把小锁合并成一把,减少次数

5. 常量折叠

(1) 什么是常量折叠

编译期间直接把常量表达式算出最终结果,运行时不再重复计算。

通俗理解:代码里写死的常量加减乘除,编译器直接帮你算好结果,运行时直接用最终值。

(2) 适用场景

  • 基本数据类型常量运算:int、long、double、boolean
  • 字符串常量拼接

(3) 关键特点

  • 只针对常量,变量不参与折叠
  • 发生在 编译期,减轻运行时计算开销
  • 属于语法糖 + 编译优化
相关推荐
m0_596749091 小时前
JavaScript中手动实现一个new操作符的底层逻辑
jvm·数据库·python
dFObBIMmai3 小时前
如何在 CSS 中实现元素的绝对定位,使其不受窗口尺寸变化影响
jvm·数据库·python
2303_821287385 小时前
如何清洗SQL输入数据_使用框架内置的ORM处理数据交互
jvm·数据库·python
电魂泡哥7 小时前
CMS垃圾回收
java·jvm·算法
weixin_444012938 小时前
如何在MongoDB中实现按时间跨度的分片路由_时间序列范围分片与冷热节点架构
jvm·数据库·python
woniu_buhui_fei9 小时前
JVM垃圾回收
java·jvm
沉下去,苦磨练!10 小时前
python的全局解释器锁(GIL)到垃圾回收机制
jvm
Co_Hui10 小时前
JVM 内存结构
jvm
Little Tomato10 小时前
深入浅出高并发:从 JVM 锁竞争到分布式事务的性能博弈
jvm·分布式