Object对象详解
一 创建对象的过程
如果方法区中没有Class对象,需要先加载类
- 1.class load
- 2.class linking(verify, prepare, resolution)
- 3.class initialization
- 4.分配对象内存
- 5.对象属性赋默认值
- 6.执行
方法
二 对象在内存中的存储布局
padding保证总字节数8的倍数
- 普通对象
属性 | mark word | class pointer | 实例数据 | padding |
---|---|---|---|---|
占用字节 | 8 | 4 | 不定 | 不定 |
- 数组对象
属性 | mark word | class pointer | 数组长度 | 元素数据 | padding |
---|---|---|---|---|---|
占用字节 | 8 | 4 | 4 | 不定 | 不定 |
注意
- -XX:+UseCompressedClassPointers 为4字节 不开启为8字节
- 引用类型:-XX:+UseCompressedOops 为4字节 不开启为8字节 Oops: Ordinary Object Pointers
对象头具体包括什么?
jvm源码位置:markOop.hpp
* 对象的内存分布
class A{
// boolean flag = false;
}
public class SynchronizeStudy {
public static void main(String[] args) {
Object a = new A();
System.out.println(ClassLayout.parseInstance(a).toPrintable());
}
}
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) 43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
小端序:数据的高位字节存放在地址的高端 低位字节存放在地址低端
-
gc分代年龄:15(4字节)
-
当一个对象计算过identityHashCode之后,不能进入偏向锁状态
https://cloud.tencent.com/developer/article/1480590
https://cloud.tencent.com/developer/article/1484167
https://cloud.tencent.com/developer/article/1485795
https://cloud.tencent.com/developer/article/1482500
对象怎么定位?
- 句柄池
定位对象耗时更长些,但对GC友好
栈中reference存储的是稳定的句柄地址,在GC导致的对象移动时,只会改变句柄中的实例数据指针,而reference本身是不需要改变的。 - 直接引用
定位对象速度更快,节省了一次指针定位的时间开销。
对象怎么分配?
为了防止移动指针导致的并发,首先会在本地线程分配缓存(TLAB)
分配内存。如果TLAB内存不足再使用CAS在堆上分配内存。