markword 中的 epoch:
批量重偏向与批量撤销渊源:从偏向锁的加锁解锁过程中可看出,当只有-个线程反复进入同步块时,偏向
锁带来的性能开销基本可以忽略,但是当有其他线程尝试获得锁时,就需要等到safe point时,再将偏向锁撤
销为无锁状态或升级为轻量级,会消耗-定的性能,所以在多线程竞争频繁的情况下,偏向锁不仅不能提高
性能,还会导致性能下降。于是,就有了批量重偏向与批量撤销的机制。
原理以clasp为单位,为每个class维护解决场景批量重偏向(bulk rebias)机制是为了解决:一个线程创建了
大量对象井执行了初始的同步操作,后来另-个线程也来将这些对象作为锁对象进行操作,这样会导致大量
的偏向锁撒销操作。批量撤销(bulk revoke)机制是为了解决:在明显多线程竞争剧烈的场景下使用偏向锁
是不合适的。
-个偏向锁撤销计数器,每一-次该class的对象发生偏向撤销操作时,该计数器+1,当这个值达到重偏向阈值
(默认20)时,JM就认为该Class的偏向锁有问题,因此会进行批量重偏向。每个class对象 会有一一个对应的
epoch字段,每个处于偏向锁状态对象的Mark Word中也有该字段,其初始值为创建该对象时class中的
epoch的值。每次发生批量重偏向时,就将该值+1,同时遍历JVM中所有线程的栈,找到该class所有正处于
加锁状态的偏向锁,将其epoch字 段改为新值。下次获得锁时,发现当前对象的epoch值和lass的epoch不相
等,那就算当前已经偏向了其他线程,也不会执行撤销操作。而是直接通过CAS操作将其Mark Word的
Thread Id改成当前线程Id.当达到重偏向阈值后,假设该classit 数器继续增长,当其达到批量撤销的阈值后
(默认40) , JM就认为该lass的使用场景存在多线程竞争,会标记该class为不可偏向, 之后,对于该class
的锁,直接走轻量级锁的逻辑。
mashibing.com/bird.html