商城首页欢迎来到中国正版软件门户

您的位置:首页 >偏向锁重偏向:解决对象大规模复用问题

偏向锁重偏向:解决对象大规模复用问题

  发布于2026-02-13 阅读(0)

扫一扫,手机访问

偏向锁重偏向触发条件是:JVM启用偏向锁、对象已偏向且原偏向线程已退出、同批对象被多个线程短时间频繁竞争导致反复撤销加锁。

什么是Java并发中的偏向锁重偏向(Bulk Rebiasing)_解决对象大规模复用

偏向锁重偏向触发条件是什么

重偏向不是自动发生的,它只在满足三个硬性条件时才可能启动:
- 当前 JVM 启用了偏向锁(-XX:+UseBiasedLocking,JDK 6–8 默认开,JDK 15+ 默认关)
- 对象已进入偏向状态,且偏向线程已退出(比如线程结束或调用了 Object.wait()
- 同一批对象(同一类实例)在短时间内被多个不同线程竞争获取锁,且每次都是“先撤销再加锁”

为什么需要 Bulk Rebiasing 而不是逐个撤销

频繁撤销偏向锁代价很高:每次撤销要停顿所有线程(safepoint),还要遍历对象头、更新 Mark Word、刷新 CPU 缓存行。当一个对象池(如 ThreadLocal 缓存的 StringBuilder)被 1000 个线程轮流复用,逐个撤销会引发上百次 safepoint,拖慢吞吐。

Bulk Rebiasing 的做法是:把这批对象打上“可批量重偏向”标记,在下一次安全点统一处理——不撤销,直接改偏向线程 ID 和 epoch 值,跳过锁膨胀流程。

关键参数:
- -XX:BiasedLockingBulkRebiasThreshold=20:同一类对象被不同线程竞争达 20 次,触发批量重偏向
- -XX:BiasedLockingDecayTime=25000(毫秒):上次批量操作后,超时则清空统计,重新计数

重偏向失败的典型现象和原因

你看到日志里反复出现 Bulk rebiasing of [class] failed,大概率是以下之一:

  • 对象已升级为轻量级锁(Mark Word 中锁标志位为 00),无法再重偏向 —— 此时只能走常规锁流程
  • 类被设置为“永不偏向”,比如通过 -XX:BiasedLockingStartupDelay=0 后又调用了 Class.revokeBias(),或该类在启动后被显式禁用(Unsafe.revokeBias()
  • 当前处于 GC safepoint 但 CMS 或 ZGC 正在并发标记,导致重偏向被跳过(JDK 8u40 后部分修复,但仍有窗口期)

怎么验证是否真在用重偏向

别只看参数开关,得看运行时行为:

启动时加:-XX:+PrintBiasedLockingStatistics -XX:+UnlockDiagnosticVMOptions
运行一段时间后执行:jcmd <pid> VM.native_memory summary 或触发 jstat -compiler <pid> 配合日志观察。

真正有效的信号是:
- 日志中出现 Bulk rebiasing <N> objects of type [class]
- jstat -printcompilation <pid> 显示 BiasedLocking 相关编译计数上升
- GC 日志里 safepoint 平均停顿时间未随对象复用频率明显增长

注意:JDK 10 开始默认关闭偏向锁,JDK 15 彻底移除;如果你用的是 JDK 17+,-XX:+UseBiasedLocking 已是无效参数,重偏向根本不会发生。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注