一个对象的size为8的倍数,对象头一般占12个字节,由于大多数CPU都是小端存储,所以存储后打印顺序是反向的。最前面的4个字节,占8个bit,32位。表示对象头中所属类型在内存中的指向。后面64位主要描述哈希code,分代年龄,锁,锁的位数只占最后3位,首位描述是否偏向,后两位描述锁的级别,01为偏向锁,00为轻量级锁,10为重量级锁,当无竞争时为偏向锁,线程交替执行为轻量级锁,出现竞争为重量级锁。另外需要提到的是,当对象调用了hashcode时,将直接变为轻量级锁,因为生成了哈希code后,生成的哈希码会把字节位占据。演示时需要将-XX:BiasedLockingStartupDelay=0设置JVM参数,偏向锁才能立即体现

    1. package com.xiangxue.springsource;
    2. import lombok.extern.slf4j.Slf4j;
    3. import org.openjdk.jol.info.ClassLayout;
    4. @Slf4j
    5. public class JolTest {
    6. static Lock lock = new Lock();
    7. public static void main(String[] args) throws InterruptedException {
    8. // System.out.println(ClassLayout.parseClass(Lock.class).toPrintable());
    9. log.debug("hashcode:{}",Integer.toHexString(lock.hashCode()));
    10. log.debug(ClassLayout.parseInstance(lock).toPrintable());
    11. Thread t1 = new Thread(()->{
    12. test();
    13. });
    14. Thread t2 = new Thread(()->{
    15. test();
    16. });
    17. t1.start();
    18. // t1.join(); //打开注释为轻量级锁
    19. t2.start();
    20. }
    21. static void test() {
    22. synchronized (lock) {
    23. try {
    24. Thread.sleep(1000);
    25. log.info(Thread.currentThread().getName());
    26. log.debug(ClassLayout.parseInstance(lock).toPrintable());
    27. } catch (InterruptedException e) {
    28. e.printStackTrace();
    29. }
    30. }
    31. }
    32. }