JAVA 对象头MarkWord

JAVA 对象头MarkWord

最近在并发编程的学习中,接触到了JAVA对象头中的MarkWord. 在此做下笔记,也和小伙伴们分享一下,共同进步!

MarkWord介绍

MarkWord是Java对象存储在内存中的一部分信息.
在32位系统中使用32位存储, 64位系统中使用64存储.以下是来自Hotspot中源码注释!

HotSpot源码注释中给出的是大端存储下的Layout.
我们平时电脑都是小端存储的,所以后续的测试结果中会出现和下图不匹配的情况!

关于大小端存储可以参考下图
图片

HotSpot源码注释

// The markOop describes the header of an object.
//
// Note that the mark is not a real oop but just a word.
// It is placed in the oop hierarchy for historical reasons.
//
// Bit-format of an object header (most significant first, big endian layout below):
//
//  32 bits:
//  --------
//  hash:25 ------------>| age:4    biased_lock:1 lock:2 (normal object)
//  JavaThread*:23 epoch:2 age:4    biased_lock:1 lock:2 (biased object)
//  size:32 ------------------------------------------>| (CMS free block)
//  PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)
//
//  64 bits:
//  --------
//  unused:25 hash:31 -->| unused:1   age:4    biased_lock:1 lock:2 (normal object)
//  JavaThread*:54 epoch:2 unused:1   age:4    biased_lock:1 lock:2 (biased object)
//  PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)
//  size:64 ----------------------------------------------------->| (CMS free block)
//
//  unused:25 hash:31 -->| cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && normal object)
//  JavaThread*:54 epoch:2 cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && biased object)
//  narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)
//  unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)

64位系统中,MarkWord结构如下
在这里插入图片描述

学习对象头,我们需要依赖一个工具JOL (JAVA OBJECT LAYOUT)可以通过pom.xml进行引入

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.14</version>
    <scope>provided</scope>
</dependency>

001 无锁,不可偏向状态

@Test
public void testUnLock() throws InterruptedException {

    System.out.println("第一次结果: ");
    System.out.println(ClassLayout.parseInstance(new Object()).toPrintable());

    Thread.sleep(4000);

    System.out.println("第二次结果: ");
    System.out.println(ClassLayout.parseInstance(new Object()).toPrintable());
}

图片

101 无锁,可偏向状态

@Test
public void testBiasedUnLock() throws InterruptedException {

    //  关闭延迟开启偏向锁
    //  -XX:BiasedLockingStartupDelay=0
    Object o = new Object();
    System.out.println("第一次结果: ");
    System.out.println(ClassLayout.parseInstance(o).toPrintable());

    int hashCode = o.hashCode();

    System.out.println("第二次结果: ");
    System.out.println(ClassLayout.parseInstance(o).toPrintable());

}

图片

101 偏向锁

static final Object lock = new Object();

@Test
public void testBiasedLock() {
    //  关闭延迟开启偏向锁
    //  -XX:BiasedLockingStartupDelay=0

    System.out.println("第一次结果: ");
    System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    synchronized (lock){
        System.out.println("加锁后结果: ");
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    }
    System.out.println("解锁后结果: ");
    System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}

图片

00 轻量锁

static final Object lock = new Object();

@Test
public void testLock() {
    //  关闭延迟开启偏向锁
    //  -XX:BiasedLockingStartupDelay=0
    synchronized (lock){
        System.out.println("主线程加锁: ");
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    }

    new Thread(()->{
        synchronized (lock){
            System.out.println("子线程加锁: ");
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    }).start();
}

图片

10 重量锁

static final Object lock = new Object();
    
@Test
public void testInflatedLock() throws InterruptedException {

    Thread t1 = new Thread(() -> {
        synchronized (lock) {
            System.out.println("t1加锁: ");
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    });

    Thread t2 = new Thread(() -> {
        synchronized (lock) {
            System.out.println("t2加锁: ");
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    });

    t1.start();
    t2.start();

    // 等待t1, t2执行完, 否则无法打印
    t1.join();
    t2.join();
}

图片

11 GC标记清除

由于标记清除是指此对象已被垃圾回收器标记成可回收对象.所以演示不出来.

图片
图片

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值