JVM:开启指针压缩后,对象位置的寻址计算

        指针压缩的技术会将Java程序中的所有引用指针(类型指针、堆引用指针、栈帧内变量引用指针等)都会压缩一半,而在Java中一个指针的大小是占一个字宽单位的,在64bit的虚拟机中一个字宽的大小为64bit,所以也就意味着在64位的虚拟机中,指针会从原本的64bit压缩为32bit的大小。

        具体原理就是,以64位虚拟机为例,由于Java会进行内存对齐,以8byte为单位对齐,所有对象的起始地址都是8字节的整数倍。所以指针的低位都是000,可以省略。而32bit指针原本可以寻址4GB的内存范围,每次乘以8复原地址之后,现在可以寻址32GB的内存范围。

        接下来介绍指针压缩后,对象位置的寻址计算:

  • ①如果堆的高位地址小于32GB(即堆中最大地址),说明不需要基址base就能定位堆中任意对象,这种模式被称为Zero-based Compressed Oops Mode,计算公式如下:
    • 计算公式:add = 0 + offset * 8
    • 计算前提:high_{heap} < 32GB
    • 解释:使用指针压缩后,地址全部位数用来表示offset,可以访问到0-32GB内存地址。如果堆最大地址也小于32GB,那么无需基地址也可以直接找到,但是偏移量需要乘以8,来复原压缩效果。
  • ②如果堆高位大于等于32GB,说明需要base基地址,这时如果堆空间小于4GB,说明基址+偏移能定位堆中任意对象,如下:
    • 计算公式:add = base + offset
    • 计算前提:size_{heap} < 4GB
    • 解释:如果高位大于32GB,意味着把0作为基地址已经无法访问到,需要添加基地址,但是,32位的指针,即使在不压缩的情况下,也可以访问到4GB的内存范围。所以如果堆空间小于4GB,把指针看做32位未压缩指针,就可以满足4GB的堆大小的寻址。
  • ③如果堆高位大于等于32GB,且堆空间大小处于4GB与32GB之间,这时只能通过基址+偏移x缩放scale(Java中缩放为8),才能定位堆中任意对象,如下:
    • 计算公式:add = base + offset * 8
    • 计算前提:4GB <= size_{heap} < 32GB
    • 解释:和之前类似。如果堆空间大于4GB,那么就不能把指针看做32位未压缩指针。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值