Java偏向锁撤销流程与性能影响
分析Java对象头中的偏向锁(Biased Locking)工作流程,包括偏向锁的获取、撤销(Revocation)时机和批量重偏向(Bulk Rebias),以及JDK 15+默认禁用偏向锁的原因。
回答
我是大山
1. 偏向锁工作原理
- Mark Word结构:偏向线程ID + epoch + 偏向标志位 + 锁标志位
- 获取流程:
- 对象初次被线程获取锁时,CAS将Thread ID写入Mark Word
- 后续同一线程再次进入同步块时,无需CAS,只需对比Thread ID
- 若一致,直接进入(无锁竞争的同步近乎零开销)
2. 偏向锁撤销(Revocation) 当其他线程尝试获取已偏向的锁时触发撤销:
- 安全点撤销:必须在全局安全点(SafePoint)执行
- 流程:
- 暂停持有偏向锁的线程(STW)
- 检查偏向线程是否存活
- 如果存活且仍在竞争,升级为轻量级锁
- 如果不竞争,撤销偏向标志
- 开销:安全点暂停是STW的,频繁撤销影响延迟
3. 批量重偏向与批量撤销
- 批量重偏向(Bulk Rebias):同一个类撤销超过20次(-XX:BiasedLockingBulkRebiasThreshold=20),JVM撤销该类所有实例的偏向
- 批量撤销(Bulk Revocation):超过40次(-XX:BiasedLockingBulkRevokeThreshold=40),彻底禁用该类的偏向锁
- Epoch机制:通过类级别的epoch批量判断是否需要重偏向
4. JDK 15+禁用原因
- 高并发应用场景下,偏向锁撤销带来的安全点暂停影响显著
- 现代应用线程池并发激烈,偏向锁收益有限
- 禁用参数:
-XX:-UseBiasedLocking - 替代方案:轻量级锁的CAS操作在现代CPU上已足够快