前言上一章节带着大家初探JVM的类加载机制,以及双亲委派机制,本文主要介绍了Java对象头的组成以及详解
一、一个对象如何组成的?对象在内存中的布局包含:对象头(Mark Word、Klass Pointer)、实例数据、对象填充
对象组成.pngMark Word :用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等Klass Pointer :对象指向它的类的元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例实例属性 :定义类中的成员属性对齐填充 : 由于HotSpot虚拟机的自动内存管理系统要求对象的起始地址必须是8字节的整数倍,也就是对象的大小必须是8字节的整数倍二、基本类型占用的字节和位数基本类型
字节
位数
byte
1 byte
8 bit
char
2 byte
16 bit
int
4 byte
32 bit
short
2 byte
16 bit
long
8 byte
64 bit
double
8 byte
64 bit
float
4 byte
32 bit
三、new 一个对象占用多少字节代码语言:java复制public class Demo1 {
public static void main(String[] args) {
LockObject lockObject = new LockObject();
System.out.println(ClassLayout.parseInstance(lockObject).toPrintable());
}
static class LockObject{
int a = 4;
long b = 1;
boolean c = false;
}
}new 一个对象占用多少字节.jpg根据上面基本类型占用的字节和位数可计算出:
在开启了指针压缩的情况下:
对象头 12个字节实例数据 int a=4 4个字节,long b=1 8个字节,boolean c=false 1个字节对齐补充 7个字节。总共32个字节四、对象内存中offset作用对象内存中offset作用.jpgoffset:相对于类对象所占内存区域起始位置的偏移
五、对象头详解哈希值:31位的对象标识hashCode,采用延迟加载技术。它是一个地址,用于栈对堆空间中对象的引用指向GC分代年龄(占4位):记录幸存者区对象被GC之后的年龄age,一般age为15(阈值为15的原因是因为age只有4位最大就可以将阈值设置15)锁状态标志(占2位):记录一些加锁的信息
偏向锁标识位
锁标志位
锁状态
存储内容
0
01
未锁定
hash code(31),年龄(4)
1
01
偏向锁
线程ID(54),时间戳(2),年龄(4)
无
00
轻量级锁
栈中锁记录的指针(64)
无
10
重量级锁
monitor的指针(64)
无
11
GC标记
空,不需要记录信息
总结本文主要介绍了Java对象头的组成以及详解