JVM——》Java对象内存模型

38 篇文章 3 订阅

推荐链接:
    总结——》【Java】
    总结——》【Mysql】
    总结——》【Spring】
    总结——》【SpringBoot】
    总结——》【MyBatis、MyBatis-Plus】

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、指针压缩的目的

  1. 为了保证CPU普通对象指针(oop)缓存
  2. 为了减少GC的发生,因为指针不压缩是8字节,这样在64位操作系统的堆上其他资源空间就少了

4、是否开启指针压缩

-- 执行java命令:查看是否开启指针压缩
java -XX:+PrintCommandLineFlags -version

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访问数据的效率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java对象内存模型包括对象头、实例数据和对齐填充三部分。对象头包含了关于堆对象的布局、类型、GC状态、同步状态和标识哈希码等基本信息。实例数据存放了类的数据信息、父类的信息以及对象字段属性信息。对齐填充主要是为了字节对齐而填充的数据,以凑齐8字节的倍数。 在JVM,我们可以使用openjdk的jol工具来打印对象信息。通过调用`ClassLayout.parseInstance(object).toPrintable()`方法,我们可以打印出对象的信息。 例如,对于一个无属性的对象,打印的信息如下: ``` java.lang.Object object internals: 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) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total ``` 这段信息描述了对象的各个部分。例如,对象头占据了前12个字节,分为三部分,每部分占4个字节。实例数据为空,所以没有具体的值。 这就是Java对象内存模型。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Java对象内存模型](https://blog.csdn.net/u013190417/article/details/122532408)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值