JAVA对象头详解(含32位虚拟机与64位虚拟机)
2021-03-19 06:24
标签:默认 数组 mon static oss 并发 运行时 stat class 学习Java对象头主要是为了解synchronized底层原理,synchronized锁升级过程,Java并发编程等。 由于Java面向对象的思想,在JVM中需要大量存储对象,存储时为了实现一些额外的功能,需要在对象中添加一些标记字段用于增强对象功能,这些标记字段组成了对象头。 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header),实例数据(Instance Data)和对齐填充(Padding)。 其中,对象头由两部分组成,一部分用于存储自身的运行时数据,称之为 Mark Word,另外一部分是类型指针,及对象指向它的类元数据的指针。 对象头 = Mark Word + 类型指针 bytes 是字节,bits 是位。所以说,在32位JVM虚拟机系统中,Mark Word部分,占了4个字节,Klass Word部分也占了4个字节,所以,对象头大小为8个字节。在64位JVM虚拟机系统中,Mark Word部分,占了8个字节,Klass Word部分也占了8个字节,所以,对象头大小为16个字节。 32位虚拟机普通对象的对象头 32位虚拟机数组对象的对象头 32位虚拟机对象头详情如下 lock:2位的锁状态标记位,由于希望用尽可能少的二进制位表示尽可能多的信息,所以设置了lock标记。该标记的值不同,整个mark word表示的含义不同。 biased_lock:对象是否启用偏向锁标记,只占1个二进制位。为1时表示对象启用偏向锁,为0时表示对象没有偏向锁。 查看对象头,就需要用到借助JOL工具。 打印,大概如下。 如果打印不一样,可以加VM options参数 要看懂VALUE这串数还得了解一下小端存储 memory-efficient-java JAVA对象头详解(含32位虚拟机与64位虚拟机) 标签:默认 数组 mon static oss 并发 运行时 stat class 原文地址:https://www.cnblogs.com/zhouwangwang/p/13763887.html为什么要学习Java对象头
JAVA对象头
也就是说 JAVA对象 = 对象头 + 实例数据 + 对象填充。
(未开启指针压缩的情况下)
在32位系统中,Mark Word = 4 bytes = 32 bits,对象头 = 8 bytes = 64 bits;
在64位系统中,Mark Word = 8 bytes = 64 bits ,对象头 = 16 bytes = 128bits;
32位虚拟机对象头
|-----------------------------------------------------------|
| Object Header (64 bits) |
|---------------------------------|-------------------------|
| Mark Word (32 bits) | Klass Word (32 bits) |
|---------------------------------|-------------------------|
|---------------------------------------------------------------------------------|
| Object Header (96 bits) |
|--------------------------------|-----------------------|------------------------|
| Mark Word(32bits) | Klass Word(32bits) | array length(32bits) |
|--------------------------------|-----------------------|------------------------|
|--------------------------------------------------------------------------------------------------------------|
| Object Header(64bits) |
|--------------------------------------------------------------------------------------------------------------|
| Mark Word(32bits) | Klass Word(32bits) | State |
|--------------------------------------------------------------------------------------------------------------|
| hashcode:25 | age:4 | biased_lock:0 | 01 | OOP to metadata object | Nomal |
|--------------------------------------------------------------------------------------------------------------|
| thread:23 | epoch:2 | age:4 | biased_lock:1 | 01 | OOP to metadata object | Biased |
|--------------------------------------------------------------------------------------------------------------|
| ptr_to_lock_record:30 | 00 | OOP to metadata object | Lightweight Locked |
|--------------------------------------------------------------------------------------------------------------|
| ptr_to_heavyweight_monitor:30 | 10 | OOP to metadata object | Heavyweight Locked |
|--------------------------------------------------------------------------------------------------------------|
| | 11 | OOP to metadata object | Marked for GC |
|--------------------------------------------------------------------------------------------------------------|
64位虚拟机对象头
|--------------------------------------------------------------------------------------------------------------|
| Object Header(128bits) |
|--------------------------------------------------------------------------------------------------------------|
| Mark Word(64bits) | Klass Word(64bits) | State |
|--------------------------------------------------------------------------------------------------------------|
| unused:25|identity_hashcode:31|unused:1|age:4|biase_lock:0| 01 | OOP to metadata object | Nomal |
|--------------------------------------------------------------------------------------------------------------|
| thread:54| epoch:2 |unused:1|age:4|biase_lock:1| 01 | OOP to metadata object | Biased |
|--------------------------------------------------------------------------------------------------------------|
| ptr_to_lock_record:62 | 00 | OOP to metadata object | Lightweight Locked |
|--------------------------------------------------------------------------------------------------------------|
| ptr_to_heavyweight_monitor:62 | 10 | OOP to metadata object | Heavyweight Locked |
|--------------------------------------------------------------------------------------------------------------|
| | 11 | OOP to metadata object | Marked for GC |
|--------------------------------------------------------------------------------------------------------------|
biased_lock
lock
状态
0
01
无锁
1
01
偏向锁
0
00
轻量级锁
0
10
重量级锁
0
11
GC标记
age:4位的Java对象年龄。在GC中,如果对象在Survivor区复制一次,年龄增加1。当对象达到设定的阈值时,将会晋升到老年代。默认情况下,并行GC的年龄阈值为15,并发GC的年龄阈值为6。由于age只有4位,所以最大值为15,这就是-XX:MaxTenuringThreshold
选项最大值为15的原因。
identity_hashcode:25位的对象标识Hash码,采用延迟加载技术。调用方法System.identityHashCode()
计算,并会将结果写到该对象头中。当对象被锁定时,该值会移动到管程Monitor中。
thread:持有偏向锁的线程ID。
epoch:偏向时间戳。
ptr_to_lock_record:指向栈中锁记录的指针。
ptr_to_heavyweight_monitor:指向管程Monitor的指针。如何查看对象头
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;
import static java.lang.System.out;
public class TestBiased {
public static void main(String[] args) {
Dog d= new Dog();
//打印JVM的详细信息
out.println(VM.current().details());
//打印对应的对象头信息
out.println(ClassLayout.parseInstance(a).toPrintable());
}
}
class Dog {
}
21:46:08.204 c.TestBiased [main] - # Running 64-bit HotSpot VM.
# Objects are 8 bytes aligned.
# Field sizes by type: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
21:46:08.215 TestBiased [main] - cn.itcast.test.Dog object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 50 c8 e1 3f (01010000 11001000 11100001 00111111) (1071761488)
12 4 (object header) 71 01 00 00 (01110001 00000001 00000000 00000000) (369)
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
-XX:-UseCompressedOops
,关闭指针压缩。
参考
深入理解Java的对象头mark word
Java对象头详解
java校招面试
Java对象结构与锁实现原理及MarkWord详解
干掉面试官1-synchronized底层原理(从Java对象头说到即时编译优化)
探究java对象头——大端存储与小端存储
文章标题:JAVA对象头详解(含32位虚拟机与64位虚拟机)
文章链接:http://soscw.com/index.php/essay/66113.html