从Java对象布局markword看syncronized的本质
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了从Java对象布局markword看syncronized的本质,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2661字,纯文字阅读大概需要4分钟。
内容图文
![从Java对象布局markword看syncronized的本质](/upload/InfoBanner/zyjiaocheng/637/aac59eaf4fd0428e8d4302bd80173d8c.jpg)
在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对象布局markword看syncronized的本质全部内容,希望文章能够帮你解决从Java对象布局markword看syncronized的本质所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。