java对象创建,应该是java程序员最熟悉的部分,一个new关键字就能触发这个过程,而在JVM中,对象的创建过程却是一个复杂的过程,涉及多个步骤和内存管理机制。
对象内存布局
一个Java对象在HotSpot虚拟机堆中的存储布局,可以分为三个连续的区域:对象头(Header)、实例数据(Instance Data)、对齐填充(padding)。
对象头
对象头是包含对象运行时元数据的关键部分,本身又由两部分(或三部分)组成。
Mark Word:是对象头中最重要的部分,用于存储对象自身的运行时数据,包括如下部分:
1、哈希码:对象的身份哈希码;
2、GC年龄分代:对象在Survivor区经历的Minor GC次数,超过阈值(默认15)则晋升老年代;
3、锁状态标志:标识对象的锁状态,是synchronized关键字实现锁升级的基础;
4、偏向线程ID:持有偏向锁的线程ID;
5、偏向时间戳等;
Mark Word采用动态结构以节省空间,其内容会根据对象的状态变化而变化;在64位JVM下,存储布局如下:
| 锁标志位 | 锁状态 | 存储内容 |
|---|---|---|
| 01 | 无锁/偏向锁 | |
| - 无锁 (Normal) | 哈希码 (25 bits) + 分代年龄 (4) + 偏向模式 (1) + 锁标志 (01) | |
| - 偏向锁 (Biased) | 线程ID (54 bits) + 时间戳 (2) + 分代年龄 (4) + 偏向模式 (1) + 锁标志 (01) | |
| 说明 | 默认状态。哈希码在调用 hashCode() 后才写入。偏向锁存储持有锁的线程ID。 | |
| 00 | 轻量级锁 | 指向栈中锁记录的指针 (62 bits) 线程通过在自己的栈帧中创建锁记录来获取锁。 |
| 10 | 重量级锁 | 指向互斥量(monitor)的指针 (62 bits) 对象关联到操作系统底层的互斥锁,线程会进入阻塞状态。 |
| 11 | GC 标记 | 空 (用于垃圾回收器标记) 在垃圾回收过程中使用,表示对象待回收或已回收。 |
类型指针(Klass Pointer):指向对象所属类元数据(Class Metadata)的指针,JVM通过这个指针来确定对象是哪个类的实例。在64位JVM上,如果开启了指针压缩,占用4个字节,关闭指针压缩,占用8个字节;
数组长度:只有对象是数组时,对象头中才有这部分,用于记录数组长度,JVM可以通过这个信息来判断数组的边界,防止数组越界访问;占用4个字节。
实例数据
是对象真正有效的信息,即我们在程序中定义的各种类型的字段内容,无论

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



