ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

从Java对象布局markword看syncronized的本质

2020-03-29 14:00:35  阅读:364  来源: 互联网

标签:Java 字节 对象 Object markword 数组 public syncronized


在HotSpot中,内存里的一个Java对象分为三部分:对象头,实例数据,对齐。其中
普通对象布局:

markword 8Bytes 用于标记锁信息、GC信息、IdentityHashCode等
Class Pointer 类指针 4Bytes 用于标记该对象是哪个Class的实例
开启内存压缩(-XX:+UseCompressedClassPointer)后为4字节,不开启内存压缩为8个字节(下面有例子)
成员变量 视成员变量的类型和数量而定 如果没有成员变量,则这一块为空
Padding 对齐 视上述字节而定 一个对象占用的字节数必须是8的倍数,不足的用padding对齐

数组对象布局:

markword 8Bytes 用于标记锁信息、GC信息、IdentityHashCode等
Class Pointer
类指针
4Bytes 用于标记该对象是哪个Class的实例
开启内存压缩(-XX:+UseCompressedClassPointer)后为4字节,
不开启内存压缩为8个字节 
数组长度 4Bytes 标记数组有多少个元素
数组内容 根据数组类型m和长度n而定,长度为m*n 如果元素为基本类型,比如byte/boolean/short/char/int/long/double,则m为对应的长度;如果元素为数组,m是4字节的引用
如果数组长度为0,这一块为空
Padding 对齐 视上述字节而定 一个对象占用的字节数必须是8的倍数,不足的用padding对齐

可以通过以下工具来查看对象的布局:JOL=Java Object Layout。 

<!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.10</version>
</dependency>

先看看普通对象的布局:编写代码:

import org.openjdk.jol.info.ClassLayout;

public class JavaObjectLayout {
    public static void main(String[] args) {
        System.out.println("------------Object---------------");
        Object o = new Object();
        String s = ClassLayout.parseInstance(o).toPrintable();
        System.out.println(s);
    }
}


可以看到,前12个字节都是object header,其中前8个字节(前两行)是markword,后4个字节(第三行)是对象指针。由于Object类没有成员变量,这块为空,因此最后4个字节(第四行)是对齐。

如果执行的时候使用JVM参数-XX:-UseCompressedClassPointers关闭类指针压缩,则class pointer将占用8字节:


同理可以查看数组对象的布局:

import org.openjdk.jol.info.ClassLayout;

public class JavaObjectLayout {
    public static void main(String[] args) {
        System.out.println("------------Object[2]---------------");
        Object[] os = new Object[2];
        System.out.println(ClassLayout.parseInstance(os).toPrintable());
    }
}


可以看到,从偏移量12开始,数组长度为4字节,值为2,然后16字节开始,为2x4=8字节的数组内容(每个Object的引用长度为4字节)。

现在,我们去掉JVM参数,并用syncronized对该对象加锁,看看markword有什么变化:

import org.openjdk.jol.info.ClassLayout;

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


可以看到,markword的前4个字节的内容发生了变化。因此,syncronized加锁的本质,是修改了该对象的markword。

 推荐:也组词

标签:Java,字节,对象,Object,markword,数组,public,syncronized
来源: https://www.cnblogs.com/1994jinnan/p/12592013.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有