一个对象的size为8的倍数,对象头一般占12个字节,由于大多数CPU都是小端存储,所以存储后打印顺序是反向的。最前面的4个字节,占8个bit,32位。表示对象头中所属类型在内存中的指向。后面64位主要描述哈希code,分代年龄,锁,锁的位数只占最后3位,首位描述是否偏向,后两位描述锁的级别,01为偏向锁,00为轻量级锁,10为重量级锁,当无竞争时为偏向锁,线程交替执行为轻量级锁,出现竞争为重量级锁。另外需要提到的是,当对象调用了hashcode时,将直接变为轻量级锁,因为生成了哈希code后,生成的哈希码会把字节位占据。演示时需要将-XX:BiasedLockingStartupDelay=0设置JVM参数,偏向锁才能立即体现
package com.xiangxue.springsource;import lombok.extern.slf4j.Slf4j;import org.openjdk.jol.info.ClassLayout;@Slf4jpublic class JolTest {static Lock lock = new Lock();public static void main(String[] args) throws InterruptedException {// System.out.println(ClassLayout.parseClass(Lock.class).toPrintable());log.debug("hashcode:{}",Integer.toHexString(lock.hashCode()));log.debug(ClassLayout.parseInstance(lock).toPrintable());Thread t1 = new Thread(()->{test();});Thread t2 = new Thread(()->{test();});t1.start();// t1.join(); //打开注释为轻量级锁t2.start();}static void test() {synchronized (lock) {try {Thread.sleep(1000);log.info(Thread.currentThread().getName());log.debug(ClassLayout.parseInstance(lock).toPrintable());} catch (InterruptedException e) {e.printStackTrace();}}}}
