通俗解析压缩指针的32GB寻址原理

zhidiantech · · 24 次点击 · · 开始浏览    
#### **基础概念:指针压缩与地址对齐** 1. **指针压缩的作用** 在64位JVM中,普通指针占用8字节。启用压缩指针后,通过 **地址对齐** 和 **位移操作**,将指针压缩到4字节。这相当于用32位的空间存储原本需要64位的信息,节省内存占用。 2. **为什么要用8字节对齐?** JVM强制所有对象按 **8字节对齐**(类似“内存格子”的最小单位是8字节)。例如: • 对象A的起始地址可能是`0x1000`(十进制4096,是8的倍数); • 对象B的起始地址可能是`0x1008`(十进制4104,也是8的倍数)。 **对齐后的地址特点**:二进制地址的后三位始终为`000`(例如`0x1000`的二进制是`0001 0000 0000 0000`,最后三位是`000`)。 --- #### **压缩指针的寻址计算** 1. **压缩存储的原理** • 由于地址是8字节对齐的,后三位`000`无实际意义,可以 **舍弃不存**。 • 例如,对象地址`0x1000`(二进制后三位`000`),压缩后存储的是`0x1000 >> 3 = 0x200`(32位数值)。 2. **解压还原的步骤** • 使用时将压缩后的32位值 **左移3位**(相当于乘以8),补上被舍弃的后三位`000`。 • 例如,压缩值`0x200`还原为真实地址:`0x200 << 3 = 0x1000`。 3. **最大寻址范围的计算** • 32位能表示的最大值是`2^32`,每个值对应8字节的内存块。 • **总寻址范围** = `2^32 × 8B = 32GB` (相当于用32个二进制位管理32GB内存,每个位代表8字节的“内存格子”)。 --- #### **为什么说“跨度是8字节,而非单字节”?** • **单字节寻址**:普通指针直接表示每个字节的地址,例如32位指针能寻址`2^32 × 1B = 4GB`。 • **压缩指针的“块寻址”**: • 每个压缩指针代表一个 **8字节的块**(类似快递柜的“格子编号”,每个编号对应一个8字节的格子)。 • 32位能表示`2^32`个块,总容量为`2^32 × 8B = 32GB`。 --- #### **实际例子** 假设堆内存中有以下对象地址(16进制): • `0x0000` → 二进制末尾`000` • `0x0008` → 二进制末尾`000` • `0x0010` → 二进制末尾`000` **压缩存储**: JVM将这些地址统一右移3位,得到压缩值`0x000`、`0x001`、`0x002`(32位数值)。 **解压还原**: 使用时左移3位,恢复为原始地址`0x0000`、`0x0008`、`0x0010`。 --- #### **关键总结** • **8字节对齐是压缩的基石**:通过舍弃地址末尾的3位`000`,将寻址粒度从1字节扩大到8字节,实现“用32位管32GB”。 • **性能与空间的平衡**: • **优点**:内存占用减少50%,提升缓存效率。 • **限制**:堆内存超过32GB时,压缩失效(需回退到8字节指针)。
24 次点击  
加入收藏 微博
上一篇:
下一篇:JVM 地址对齐
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传