推荐链接:
总结——》【Java】
总结——》【Mysql】
总结——》【Spring】
总结——》【SpringBoot】
总结——》【MyBatis、MyBatis-Plus】
JVM——》Java对象内存模型
一、Mark Word
1、Mark Word在HotSpot的实现
二、Class Pointer
1、内存模型设计
(1)句柄池访问对象
在堆中开辟一块内存作为句柄池,句柄中储存了对象实例数据(属性值结构体) 的内存地址,访问类型数据的内存地址(类信息,方法类型信息),对象实例数据一般也在heap中开辟,类型数据一般储存在方法区中。
Q:优点?
A:reference存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为) 时只会改变句柄中的实例数据指针,而reference本身不需要改变。
Q:缺点?
A:增加了一次指针定位的时间开销。
(2)直接指针访问对象
reference中直接储存对象在heap中的内存地址,但对应的类型数据访问地址需要在实例中存储。
优点:节省了一次指针定位的开销。
缺点:在对象被移动时(如进行GC后的内存重新排列),reference本身需要被修改。
2、指针占用字节数
JVM是64位系统,根据是否开启指针压缩UseCompressedClassPointers,占用字节数不一样
- 不开启指针压缩:8字节
- 开启指针压缩:4字节
3、指针压缩的目的
- 为了保证CPU普通对象指针(oop)缓存
- 为了减少GC的发生,因为指针不压缩是8字节,这样在64位操作系统的堆上其他资源空间就少了
4、是否开启指针压缩
-- 执行java命令:查看是否开启指针压缩
java -XX:+PrintCommandLineFlags -version
内存 < 4G:默认不开启
内存 > 4G:默认开启
内存 > 32G:无法开启(指针压缩失效)
(1)为什么32G针压缩失效?
如果是32位系统,CPU 最大支持2^32 = 4G
如果是64位系统,CPU最大支持 2^64
但是对其填充是按照8字节进行填充,指针压缩可以理解为在32位系统在64位上面使用,因为32位系统的CPU寻址空间最大支持4G,对其填充*8 = 32G,这就是内存>32G指针压缩失效的原因。
(2)开启压缩后只占用4字节,为什么可以支持32G寻址(正常只能支持4G的寻址)
因为对象的对齐填充。
所有对象开头的位置,必须是8n的位置,所以寻址时,从0到8到16到24到32。
按照之前8倍的方式去找对象,寻址范围自然是之前的8倍。
三、对齐填充
1、对齐填充的目的
提高CPU访问数据的效率