Synchronize 偏向锁,轻量级锁升级和撤销过程,对象头的变化
(锁源码文件:bytecodeInterpreter.cpp)
问题:
1 偏向锁加锁前,加锁中,加锁后头变化
2 偏向锁升级轻量级锁,升级前,轻量锁,和轻量级锁完成对象头变化
结论:
1 偏向锁加锁前,对象头标识 101,没有保存线程ID
2 偏向锁加锁 ,对象头标识101,保存线程ID(1 当前线程中创建一个Lock Recode 2 所记录中的指针指向对象头)
3 偏向锁加锁后:对象头标识101,保存线程ID,如果同一个线程过来请求则对比线程ID,线程还是偏向锁
4偏向锁锁升级为轻量级锁前:对象头为101,存在线程ID ,第4步到5步骤偏向锁升级,中间会有偏向锁撤销,然后才升级轻量锁,这个会有性能损耗
5 轻量级锁加锁时候:对象头000,保存线程锁记录的指针(1 创建锁记录 2 所记录指针指向对象头 3对象头指针指向所记录 )
6 轻量级锁完成后:对象头001,无线程ID和所记录指针的保存
对于轻量级锁释放以后有新线程过来加锁:
1 生成一个无锁的markword(001)
2 将无锁的markword 替换掉线程中的所记录中的markword
3 用cas判断对象头中的markword标识的值和内存中生成的值(001)是否相同
4 如果相同,则将对象头中的指针指向栈帧中的所记录
5 如果不同,则可能是有新线程已经加锁,则当前锁需要膨胀为重量级锁
6 将对象头的标识为改成 00
测试代码:
package com.test;//package com.test; import org.openjdk.jol.info.ClassLayout; import java.util.concurrent.locks.LockSupport; /** * Hello world! *-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -XX:-UseCompressedOops 指针压缩测试 * -Xms1g -Xmx1g -XX:+PrintGCDetails -XX:BiasedLockingStartupDelay=0 偏向延迟关闭参数 */ public class Test4 { static Thread t1=null; static Thread t2 = null; public static void main( String[] args ) throws InterruptedException { B b = new B(); t1 = new Thread(){ @Override public void run() { System.out.println( Thread.currentThread().getId()); System.out.println(ClassLayout.parseInstance(b).toPrintable()); synchronized (b){ System.out.println(ClassLayout.parseInstance(b).toPrintable()); } System.out.println(ClassLayout.parseInstance(b).toPrintable()); LockSupport.unpark(t2); } }; t2 = new Thread( ){ @Override public void run() { LockSupport.park(); System.out.println("线程2开始执行======"); System.out.println( Thread.currentThread().getId()); System.out.println(ClassLayout.parseInstance(b).toPrintable()); synchronized (b){ System.out.println(ClassLayout.parseInstance(b).toPrintable()); } System.out.println(ClassLayout.parseInstance(b).toPrintable()); } }; t1.start(); t2.start(); t1.join(); t2.join(); } }
最终打印结果:
com.test.B object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total com.test.B object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 05 b0 93 1e (00000101 10110000 10010011 00011110) (512995333) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total com.test.B object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 05 b0 93 1e (00000101 10110000 10010011 00011110) (512995333) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total 线程2开始执行====== 13 com.test.B object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 05 b0 93 1e (00000101 10110000 10010011 00011110) (512995333) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total com.test.B object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 10 f3 c3 1f (00010000 11110011 11000011 00011111) (532935440) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total com.test.B object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total