1. 对象内部结构

一个对象内部结构由对象头、实例成员以及对齐填充组成。其中对象头由64位的Mark Word以及元数据指针和数组长度(只有数组对象才有)组成,其中元数据指针指向的是元空间中该对象的类.class。其中Mark Word包括一位偏向状态和两位锁状态标志,如下图。

2. 内部结构查看

2.1 jor-core插件下载

首先,我们去maven仓库下载一个jol-core插件或者在pom.xml中配置一下依赖,我这边使用的是IDEA2020版,所以下载了2020年的一个版本,如下图。

2.2 对象内部结构分析

2.2.1 不是数组对象,而且有填充补齐位。填充补齐位为了凑成8个字节,64位,方便64位系统寻址。

2.2.2 不是数组对象,且没有填充补齐位

2.2.3 数组对象

3. 锁升级或降级过程的锁标志位

3.1 偏向锁的启用和延时

3.1.1 偏向锁是否启用,可通过-XX:+UseBiasedLocking开启偏向锁以及-XX:-UseBiasedLocking关闭偏向锁;偏向锁启动延时时间,可通过-XX:BiasedLockingStartupDealy变量设置时间,ms为单位。通过 java -XX:+PrintFlagsFinal -version | findstr "BiasedLocking" 可查看java关于偏向锁的默认设置,如下图。

3.1.2 启动偏向锁,并设定偏向锁启动延迟时间为4s,如下图。

3.2 偏向锁升级、膨胀过程(本节操作都是在开启偏向锁,而且延时为0的场景下)

3.2.1 升级为偏向锁,高位的三位锁标志是101(带线程id);释放锁不会降级。

3.2.2 升级为轻量级锁,高位的锁标志是两位00。如果抢锁的线程和对象头内偏向锁记录的线程不一致时,升级为轻量级锁;

注意,其它博客提到的这么一句话:如果偏向锁的那个偏向线程不存在,锁不升级。经过实践,仍然还是升级为轻量级锁了!!!

3.2.3 再次抢锁时,直接从无锁状态变为轻量级锁,然后释放锁又降级为无锁状态

3.2.4 只要两个线程同时争抢,那么线程直接就升级为重量级锁,不管原先是什么锁状态;而且释放锁后,也不会降级。

这边需要提一下Lock Record,每一个线程在抢锁时,都会先在线程的栈帧中创建存储Lock Record的空间(存储共享对象的Mark Word的拷贝);然后每个线程抢锁时都会尝试将共享对象的Mark Word指向自己的Lock Record。最终,共享对象的Mark Word会存储抢锁成功线程的Lock Record地址;那些抢锁失败的线程会CAS自旋一定次数,如果在指定次数内成功了(默认10次),那么就更改共享对象的Mark Word;如果指定次数后仍不成功,就将锁升级为重量级锁了。

附录

最终出现了一个问题,系统开启偏向锁,两个线程间隔100ms抢锁后都是偏向锁,第二个线程抢锁没有升级为轻量级锁;而且两次对象头内容都一样,为什么???

当两个线程抢锁的时间间隔改为20ms,锁升级变化过程又正常了。

分析对象内部结构,并详解synchronized锁膨胀升级和降级的过程相关推荐

  1. 详解synchronized锁的各种用法及注意事项

    1 前言 本文主要通过简单的demo来阐述synchronized锁的各种用法以及使用synchronized锁的相关注意事项,记录下来同时也方便自己记忆. synchronized锁是jvm内置的锁 ...

  2. Java多线程系列(六):深入详解Synchronized同步锁的底层实现

    谈到多线程就不得不谈到Synchronized,很多同学只会使用,缺不是很明白整个Synchronized的底层实现原理,这也是面试经常被问到的环节,比如: synchronized的底层实现原理 s ...

  3. AQS基础——多图详解CLH锁的原理与实现

    1 什么是自旋锁和互斥锁? 由于CLH锁是一种自旋锁,那么我们先来看看自旋锁是什么? 自旋锁说白了也是一种互斥锁,只不过没有抢到锁的线程会一直自旋等待锁的释放,处于busy-waiting的状态,此时 ...

  4. 多线程---详解各种锁和AQS原理

    详解各种锁与锁的使用 1. synchronized 可重入 同一个线程 不同线程 2. volatile 保证线程可见性 禁止指令重排序 查看结果 3. 锁优化 锁细化 锁粗化 锁对象 4. CAS ...

  5. 【C++】C++对象模型:对象内存布局详解(C#实例)

    C++对象模型:对象内存布局详解 0.前言 C++对象的内存布局.虚表指针.虚基类指针解的探讨,参考. 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可 ...

  6. Android 事件分发机制分析及源码详解

    Android 事件分发机制分析及源码详解 文章目录 Android 事件分发机制分析及源码详解 事件的定义 事件分发序列模型 分发序列 分发模型 事件分发对象及相关方法 源码分析 事件分发总结 一般 ...

  7. php输出源代码,PHP源代码分析-echo实现详解

    PHP源代码分析-echo实现详解 echo,这个是PHP运用得最多的标记之一,算不上是函数,PHP手册里这么写的,因为它没有返回值.今天好奇就去看看PHP的源代码,因为echo不是一般的函数,所以找 ...

  8. Hibernate对象关系映射详解之一对多关系映射

    Hibernate对象关系映射详解之"一对多"关系映射 之前学习Hibernate框架的时候,对这七大关系映射一直是云里雾里的,虽然可以仿照写出代码,但是不能独立编写出来.鉴于工作 ...

  9. Beetle.SL对象封装协议详解

    Beetle.SL给Silverlight提供了WCF以外的基于对象传送的Socket tcp传输功能,虽然提供了对象来描述协议但如果对其协议的封不了解那似乎和其他平台进行网络通过就比较麻烦了.虽然B ...

最新文章

  1. 什么时候应该在内部联接上使用交叉应用?
  2. os_mutex.c(全)
  3. VTK:PolyData之FieldData
  4. fatal error C1083: 无法打开包括文件:dxtrans.h: No such file or directory
  5. 求背包问题所有解(C++实现)
  6. 泡着枸杞写bug的三流程序员凭什么逆袭到一线大厂?
  7. 3W | 跟着小小学会这些 Java 工程师面试题,月薪至少 3 W
  8. Filezilla软件
  9. 【数据集】机器学习数据集汇总(附下载地址)
  10. 使用Spider提取数据(爬取起点中文网)
  11. fiddler抓包记录
  12. font-family常用字体集合
  13. java中创建一个类
  14. 台式计算机的显卡,台式电脑显卡天梯图-台式机显卡性能排名
  15. 如何使用Python抓取移动端APP的评论(小白篇)
  16. 玩客云:更好的迅雷从“共享计算”开始
  17. ORB词袋特征提取和匹配
  18. 关于页面访问 404的具体解决办法
  19. codeforces 711C Coloring Trees(DP)
  20. Excel简单宏定义(快速合并多个表格,合并多个工作表,合并特定工作表)

热门文章

  1. 【MM模块】Batch 批次管理 2
  2. 【增强】FI行项目报表增强任意字段
  3. 【重复制造精讲】1、入门介绍
  4. win7 64位数据库连接问题:在指定的 DSN 中,驱动程序和应用程序之间的体系结构不匹配
  5. SAP BASIS顾问认知的一些误区
  6. 通过这组数据分析发现房价波动背后的规律
  7. 透过三翼鸟,看品牌背后的“有效创新”
  8. 这届不敢看体检报告的年轻人还能“年轻”多久?
  9. ajax等待进度数,如果ajax少于X秒,如何延迟显示进度?
  10. 重庆职高统考c语言,2021年重庆市中职毕业生参加高职分类考试招生文化素质测试 考试说明...