【转】谈谈 JVM 内部锁升级过程

一、加锁发生了什么

//System.out.println都加了锁
public void println(String x) {
  synchronized (this) {
    print(x);
    newLine();
  }
}

简单加锁发生了什么?

要弄清楚加锁之后到底发生了什么需要看一下对象创建之后再内存中的布局是个什么样的?

一个对象在 new 出来之后在内存中主要分为 4 个部分:

  • Markword 这部分其实就是加锁的核心,同时还包含的对象的一些生命信息,例如是否 GC、进过了几次 Young GC 还存活等。
  • klass pointer 记录了指向对象的 class 文件指针。
  • instance data 记录了对象里面的变量数据。
  • padding 作为对齐使用,对象在 64 位服务器版本中,规定对象内存必须要能被 8 字节整除,如果不能整除,那么就靠对齐来补。举个例子:new 出了一个对象,内存只占用 18 字节,但是规定要能被 8 整除,所以 padding=6。
    【转】谈谈 JVM 内部锁升级过程

知道了这 4 个部分之后,我们来验证一下底层。借助于第三方包 JOL = Java Object Layout java 内存布局去看看。很简单的几行代码就可以看到内存布局的样式:

<!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
<dependency>
    <groupid>org.openjdk.jol</groupid>
    <artifactid>jol-core</artifactid>
    <version>0.9</version>
</dependency>
public class JOLDemo {
    private static Object  o;
    public static void main(String[] args) {
        o = new Object();
        synchronized (o){
            System.out.println(ClassLayout.parseInstance(o).toPrintable());
        }
    }
}

将结果打印出来:

【转】谈谈 JVM 内部锁升级过程

从输出结果看:

  1. 对象头包含了 12 个字节分为 3 行,其中前 2 行其实就是 Markword,第三行就是 klass 指针。值得注意的是在加锁前后输出从 001 变成了 000。Markword 用处:8 字节(64bit)的头记录一些信息,锁就是修改了 Markword 的内容 8 字节(64bit)的头记录一些信息,锁就是修改了markword的内容字节(64bit)的头记录一些信息。从 001 无锁状态,变成了 00 轻量级锁状态。
    【转】谈谈 JVM 内部锁升级过程
  2. new 出一个 object 对象,占用 16 个字节。对象头占用 12 字节,由于 Object 中没有额外的变量,所以 instance = 0,考虑要对象内存大小要被 8 字节整除,那么 padding=4,最 后 new Object() 内存大小为 16 字节。

二、锁的升级过程

2.1 锁的升级验证

探讨锁的升级之前,先做个实验。两份代码,不同之处在于一个中途让它睡了5秒,一个没睡。看看是否有区别。

`
public class JOLDemo {
private static Object o;
public static void main(String[] args) {
o = new Object();
synchronized (o){
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
}
}

Original: https://www.cnblogs.com/jmcui/p/14959773.html
Author: JMCui
Title: 【转】谈谈 JVM 内部锁升级过程

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/619763/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • SQLI-LABS(Less-11、12)

    Less-11(POST-Error Based-Single Quotes-String) 打开 Less-11的页面,可以看到一个登录框,需要输入用户名和密码,由本关名字可知S…

    Linux 2023年6月6日
    072
  • Linux磁盘管理

    一、磁盘管理 Linux 磁盘管理好坏直接关系到整个系统的性能问题。 Linux 磁盘管理常用的三个命令为 df、 du 和 fdisk。 df(英文全称:disk full):列…

    Linux 2023年5月27日
    088
  • windows环境下启动多个redis服务(搭建redis集群)

    windows环境下启动多个redis服务(搭建redis集群一) 最终效果:本地安装好3个(多个)端口的redis服务。 1.下载并安装Redis 下载地址:https://gi…

    Linux 2023年5月28日
    088
  • 【spring-boot】Redis的整合与使用详解

    在pom.xml中添加依赖 org.springframework.boot spring-boot-starter-data-redis 2.2.1.RELEASE io.let…

    Linux 2023年5月28日
    084
  • windows-cmd-help结果集

    有关某个命令的详细信息,请键入 HELP 命令名ASSOC 显示或修改文件扩展名关联。ATTRIB 显示或更改文件属性。BREAK 设置或清除扩展式 CTRL+C 检查。BCDED…

    Linux 2023年6月7日
    073
  • [转帖]bash shell学习之变量

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年5月28日
    079
  • Go语言中的零值坑记

    开箱即用 什么叫开箱即用呢?因为 Go语言的零值让程序变得更简单了,有些场景我们不需要显示初始化就可以直接用,举几个例子: 切片,他的零值是 nil,即使不用 make进行初始化也…

    Linux 2023年6月6日
    0111
  • Docker-数据卷管理

    Docker-数据卷管理 1.利用数据卷和数据容器管理数 管理Docker 容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器( DataVolumes Co…

    Linux 2023年6月13日
    080
  • Identity Server 4使用OpenID Connect添加用户身份验证(三)

    一、说明 基于上一篇文章中的代码进行继续延伸,只需要小小的改动即可,不明白的地方可以先看看本人上一篇文章及源码: Identity Server 4资源拥有者密码认证控制访问API…

    Linux 2023年6月13日
    078
  • [ Python ] PyQt5 PySide2 笔记

    https://www.cnblogs.com/yeungchie/ PyQt5 from PyQt5.QtWidgets import * from PyQt5.QtCore i…

    Linux 2023年6月7日
    087
  • 一篇文章剖析设计模式中的简单工厂、工厂方法和抽象工厂

    前言 大部分的面试者在IT行业面试中,提及设计模式,可以列举一大堆,但是面试官要求细说的时候,往往部分基础不够牢固的同学只能提及简单工厂。今天我们来对面试过程中最常见的简单工厂、工…

    Linux 2023年6月13日
    091
  • 【原创】Linux虚拟化KVM-Qemu分析(三)之KVM源码(1)

    背景 Read the fucking source code! –By 鲁迅 A picture is worth a thousand words. –…

    Linux 2023年6月8日
    078
  • 招人、找人、找大牛啦!

    招人、找人、找大牛啦! 有意从事、投资TO B业务,含新型操作系统、大数据、人工智能、高性能计算、分布式应用软件的研发、高管、合伙人朋友请联系我,我司正在启动新一轮业务拓展!详情私…

    Linux 2023年6月6日
    087
  • 【AutoSAR】 CP 和 AP

    概述 AutoSAR,全称为Automotive Open System Architecture(汽车开放系统架构)。是由全球各家汽车制造商、零部件供应商以及各种研究、服务机构共…

    Linux 2023年6月13日
    0110
  • kafka 在 zookeeper 中保存的数据内容

    转载请注明出处: 服务器上下载 kafka : wget https://archive.apache.org/dist/kafka/2.4.0/kafka_2.12-3.2.0….

    Linux 2023年6月14日
    084
  • 第二周作业

    第二周作业 一、显示在/etc目录下,以非字母开头,后面跟了一个字母以及其它任意长度任意字符的文件或者目录 [root@CentOS8 / ]#!mkdir mkdir /etc/…

    Linux 2023年6月13日
    087
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球