首页  

JVM中的对象内存布局     所属分类 java 浏览量 1348
创建对象的方式
new  反射机制 Object.clone 反序列化  Unsafe.allocateInstance 

Unsafe.allocateInstance不会初始化实例字段
new  和反射机制 通过调用构造器来初始化实例字段


没有定义构造函数 自动添加一个无参数的构造函数(默认构造函数)

如果父类没有默认构造器,子类的构造函数需要显式地调用父类带参数的构造函数

super  this 

Java 对象  对象头
标记字段  类型指针 

存储 Java对象的运行数据,如哈希码、GC 信息以及锁信息,类型指针则指向该对象的类。 

64位JVM中,对象头标记字段占 64 位,类型指针占 64 位。 每个 Java 对象在内存中的额外开销是 16 字节。 

压缩指针 将堆中64位的Java对象指针压缩成32位
内存对齐  JVM堆中对象的起始地址需要对齐至8的倍数   对象间的填充

指针里存放地址,由于堆中对象的起始地址对齐至8的倍数,所以指针存放一个引用(或者对象的类)的内存地址时,不用存放最后的三位二进制数。
因为所有对象或类的内存地址都对齐了8,内存地址的最低三位总是0,32位的指针可以寻址到 2 的 35 次方个字节,
也就是 32GB 的地址空间(超过 32GB 则会关闭压缩指针)。

Java 虚拟机要求long字段、double字段,以及非压缩指针状态下的引用字段地址为8的倍数。 
        
CPU的缓存行机制  如果字段不对齐,有可能出现跨缓存行的字段。     
该字段的读取可能需要替换两个缓存行,而该字段的存储也会同时污染两个缓存行。

伪共享
同一对象中不同的 volatile 字段,逻辑上它们并没有共享内容,因此不需要同步。
如果这两个字段恰好在同一个缓存行中,那么对这些字段的写操作会导致缓存行的写回,也就造成了实质上的共享。

Java8 引入 @Contended,用来解决对象字段之间的伪共享。

Java 虚拟机 让不同的 @Contended 字段处于独立的缓存行中, 避免无谓的缓存行同步操作。

jvm参数加上 -XX:-RestrictContended    @Contended注解才会生效

上一篇     下一篇
37种融资模式

企业分析要点

linux打开文件最大数设置

判断文件是否是符号链接

maven clean package install deploy区别

jar冲突处理