• JUC并发编程:Monitor和对象结构


    1. Monitor

    Monitor官方文档

           我们可以把Monitor理解为一个同步工具,也可以认为是一种同步机制。它通常被描述为一个对象,所有的Java对象都是天生的Monitor,每一个Java对象都有成为Monitor的潜质。因为在Java的设计中 ,每一个Java对象都带了一把看不见的锁,它叫做内部锁或者Monitor锁。

           Monitor 是线程私有的数据结构,每一个线程都有一个可用monitor record列表,同时还有一个全局的可用列表。每一个被锁住的对象都会和一个monitor关联(对象头的MarkWord中的LockWord指向monitor的起始地址),同时monitor中有一个Owner字段存放拥有该锁的线程的唯一标识,表示该锁被这个线程占用。

    moniter结构:

           获取对象锁的过程,其实是获取monitor对象的所有权的过程。哪个线程持有了monitor对象,那么哪个线程就获得了锁,获得了锁的对象可以重复的来获取monitor对象,但是同一个线程每获取一次monitor对象所有权锁计数就加一,在解锁的时候也是需要将锁计数减成0才算真的释放了锁。
           monitor对象,我们其实在Java的反编译文件中并没有看到。这个对象是存放在对象头中的。

    1.1 对象的结构

           在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。所谓对齐填充是指如果对象总大小不是4字节的整数倍,会填充上一段内存地址使之成为整数倍。

    下图所示为64位JVM堆中的Java对象结构:
    在这里插入图片描述
    对象头在对象的最前端,包含两部分或者三部分:Mark Word、Klass Word,如果对象是一个数组,那么还可能包含第三部分:数组的长度。

    1.1.1 MarkWord

           MarkWord主要存储对象运行时的一部分数据,这里面主要包含对象的hashcode、GC年龄分代、synchronized锁信息(锁状态标志位、线程锁标记、偏向线程ID、偏向时间戳)等等。

           MarkWord 在32位和64位虚拟机上的大小分别位32bit 和 64bit,它的最后 2 bit 是锁标志位,用来标记当前对象的状态。

    在这里插入图片描述

    1.1.2 Klass Word

           里面存的是一个地址,占32位或64位,是一个指向当前对象所属于的类的地址,可以通过这个地址获取到它的元数据信息。klass 包含类的元数据信息,像类的方法,常量池等。你可以把它当作 java 里的 java.lang.Class 对象。

           如果应用的对象过多,使用64位的指针将浪费大量内存。64位的JVM比32位的JVM多耗费50%的内存。 现在使用的64位 JVM会默认使用选项+UseCompressedOops 开启指针压缩,将指针压缩至32位。

    1.1.3 数组长度

           如果这个对象是数组类对象,那么如上图右侧所示,会在对象头里额外的添加一个记录数组长度的字段。

    以64位操作系统为例,对象头存储内容图例

    在这里插入图片描述

    • age:Java GC标记位对象年龄。
    • identity_hashcode:对象标识Hash码,采用延迟加载技术。当对象使用HashCode()计算后,并会将结果写到该对象头中。当对象被锁定时,该值会移动到线程Monitor中。
    • thread:持有偏向锁的线程ID和其他信息。这个线程ID并不是JVM分配的线程ID号,和Java Thread中的ID是两个概念。
    • epoch:偏向时间戳。
    • ptr_to_lock_record:指向栈中锁记录的指针。
    • ptr_to_heavyweight_monitor:指向线程Monitor的指针。

    1.1.4 🌰

    class Student{
        boolean flag=false;
    }
    public class Test1 {
        public static void main(String[] args) {
            Student student=new Student();
            System.out.println(ClassLayout.parseInstance(student).toPrintable());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

  • 相关阅读:
    ArrayList扩容源码解析
    两个有序数组的合并(python)
    分享三款AI智能修图工具,超实用!
    【linux】登录审计
    COLING 2022 | CSL-大规模中文科学文献数据集
    计算机毕业设计node.js+Vue+Element企业员工信息管理系统
    【网络协议】 TCP与UDP协议区别及应用场景深度分析
    《传统文化典藏馆》前端模板
    MySQL主从复制(基于GTID--事务ID方式)
    Django实战:从零到一构建安全高效的Web应用
  • 原文地址:https://blog.csdn.net/Blue_Pepsi_Cola/article/details/133759697