JVM-指针压缩

发布于:2025-09-02 ⋅ 阅读:(16) ⋅ 点赞:(0)

1. 关键前提

  • 对象地址对齐:JVM中所有对象地址按8字节对齐(最低3位必为000
  • 32GB堆内存范围0x000000000 ~ 0x7FFFFFFFF(35位地址空间)
  • 压缩目标:将64位指针压缩为32位存储

2. 32GB堆最大地址的二进制分析

(1)最大64位地址(32GB边界)

十六进制:0x7FFFFFFFF   
完整二进制:   
0000 0000 0000 0000 0000 0000 0111 1111 1111 1111 1111 1111 1111 1111 1111 1000   
(实际有效35位:第0-34位)

(2)关键特征

有效地址部分:111 1111 1111 1111 1111 1111 1111 1111 1111 1000(35位)   
对齐特征:_______________________________↑↑↑
                                    固定为000(3位)

3. 压缩过程(64位→32位)

(1)右移3位(丢弃对齐位)

原始地址:111 1111 1111 1111 1111 1111 1111 1111 1111 1000   
右移3位:  000 1111 1111 1111 1111 1111 1111 1111 1111 1111   

(2)截取低32位

截取结果:1111 1111 1111 1111 1111 1111 1111 1111(0xFFFFFFFF)
存储内容:32位压缩指针 = 0xFFFFFFFF

4. 解压过程(32位→64位)

(1)左移3位(恢复对齐位)

压缩指针:1111 1111 1111 1111 1111 1111 1111 1111   
左移3位:1111 1111 1111 1111 1111 1111 1111 1111 1000   


(2)补零扩展至64位

最终地址:0000 0000 0000 0000 0000 0000 0111 1111 1111 1111 1111 1111 1111 1111 1111 1000
          = 0x000000007FFFFFFFF(原始地址)

5. 关键点总结

  1. 为什么是3位?

    • 8字节对齐 ⇒ 地址是8的倍数 ⇒ 二进制末尾3位=​000​ ⇒ 这3位无需存储。
  2. 32位如何覆盖35位空间?

    • 压缩后32位的每个单位实际代表8字节(因为左移3位相当于 ​×8​),因此总地址空间为:

  1. 2^32×8=2^35=32GB

32位能表示的地址个数为:2^32=4G

每个地址8字节对齐:4G*8 =32G

问题:不右移已经能表示32G内存了,为什么还要右移?

操作 目的 数学本质 硬件支持优势
右移3位 将字节地址转换为块索引 物理地址 ÷ 8 取代低速除法指令
左移3位 将块索引还原为物理地址 块索引 × 8 匹配CPU缓存行


网站公告

今日签到

点亮在社区的每一天
去签到