java对象中的内存布局详解--Java虚拟机

java对象中的内存布局

在虚拟机中,一个对象在堆内存中的存储可以分为三个部分:对象头(Header),实例对象(Instance Data)和对齐填充(Padding).下面我们就来了解一个这三个部分分别是什么,以及它们的作用.

1.对象头

对象头又分为两个部分.Mark Word 和 Klass Word(不要怀疑,就是Klass,不是class).它们在不同的JVM中大小占比也是不同的.下文默认JVM为HotSpot虚拟机32位.

概述 32位虚拟机 64位虚拟机
Mark Word 存储对象运行时数据 32bit 64bit
Klass Word 类型指针,指向对象的类型元数据 32bit 64bit
Array Lenght(数组对象独有) 数据的长度 32bit 64bit

1 Mark Word

MarkWord 主要是用于存储对象本身的运行时数据:哈希码(HashCode),GC分代年龄(age),锁信息等.对象需要存储的运行时数据有很多,如果都存储起来就会超过32位.考虑到虚拟机的空间效率,MarkWord被设计成一个有着动态定义的数据结构.既一个对象的MarkWord会根据不同的状态来存储不同的数据.下面是几种情况.

|-------------------------------------------------------------|--------------------|
|                  Mark Word (32 bits)                        |       State        |
|-------------------------------------------------------------|--------------------|
| identity_hashcode:25 | age:4 | biased_lock:1(0)| lock:2(01) |       Normal       |
|-------------------------------------------------------------|--------------------|
|  thread:23 | epoch:2 | age:4 | biased_lock:1(1) | lock:2(01)|       Biased       |
|-------------------------------------------------------------|--------------------|
|               ptr_to_lock_record:30          | lock:2(00)   | Lightweight Locked |
|-------------------------------------------------------------|--------------------|
|               ptr_to_heavyweight_monitor:30  | lock:2(10)   | Heavyweight Locked |
|-------------------------------------------------------------|--------------------|
|                                              | lock:2(11)   |    Marked for GC   |
|-------------------------------------------------------------|--------------------|
        后面的()中的内容代表在该特定状况下的二级制值,比如lock在Normal状况下占两位,值为(01)

下面对其中的数据进行解释.

  • identity_hashcode:对象的HashCode,事实上,如果一个对象没有调用hashCode()方法,那么这个对象的identity_hashcode的值就是0.
  • age:java对象的GC分代年龄.
  • biased_lock:对象是否开启偏向锁.1代表开启偏向锁.
  • lcok:锁的状态标志.有表格可知,当 biased_lock为0,lock为01时,对象为无锁状态.lock为00时,代表为重量级锁.10为轻量级锁.11位GC标志
  • ptr_to_lock_record:指向该对象的锁的线程的lock_record
  • ptr_to_heavyweight_monitor:指向该对象的Monitor指针.

1.2Klass Pointer

类型指针,一个对象通过该指针就可以知道该对象是哪个类的实例.

1.3Array Length

记录数组的长度.但是如果一个数组的对象的长度是不确定的,那么将无法通过元数据中的信息推断出数组的大小

2.实例数据(Instance Data)

实例部分数据则是对象中存储的真正有效的信息,既程序员设定的各类属性值.

3.对齐填充(Padding)

这部分内容不是必须存在的,也没有什么特殊含义,但是由于HotSpot虚拟机规定对象的起始地址必须是8字节(32位).对象的对象头一定是8字节的整数倍.所以如果实例部分的不是整数倍就要加上一点占位符来达到要求.

猜你喜欢

转载自blog.csdn.net/qq_44823898/article/details/109785206