java对象指针压缩

java对象指针压缩

  • 对于64位的JVM,开启压缩指针优化后,64位的CPU寄存器只需要使用其中的32位进行内存寻址,就可以访问到最多32G的堆内存,这是怎么做到的?32位寻址不是只能访问到最多4G的内存吗?
  • 做法:CPU将32位的值进行左移3位,变成35位,利用这35位进行寻址,由2的35次方可知确实能访问到最多32G的堆内存。
    • 若32位的值为0x00000000,左移后变成了0x00000000,访问到了堆内存的第0个字节;若32位的值为0x00000001,左移后变成了0x00000008,访问到了堆内存的第8个字节;若32位的值为0x00000010,左移后变成了0x00000010,访问到了堆内存的第16个字节…
    • 也就是说,只能寻址到相隔8个字节的内存地址,无法访问到中间的一些地址,而8个字节刚好与JVM要求的对象大小必须是8字节对齐相吻合,不会影响对象的寻址。
  • 因此,开启压缩指针优化后,对于64位的JVM,引用类型的大小为32位。
  • 好处:在没有开启压缩指针之前,对于64位的JVM,引用类型的大小为64位,当引用类型保存在堆中的时候,64位相比32位多出了4个字节,占据空间更大,导致GC频率高;当引用类型保存在CPU缓存中(虚拟机栈的局部变量表)的时候,占用缓存空间。开启了压缩指针后,这两个问题得到了有效的解决。
  • 总结,对于64位的JVM,若堆内存不超过32G,开启压缩指针优化性能更好.
  • 下面这段英文解释有助于理解压缩指针。引用自:https://tianshuang.me/2017/04/Java-%E5%AF%B9%E8%B1%A1%E6%8C%87%E9%92%88%E5%8E%8B%E7%BC%A9/index.html。
  • Let’s talk a bit about Ordinary Object Pointers (OOPs) and Compressed OOPs (Coops). OOPs are the handles/pointers the JVM uses as object references. When oops are only 32 bits long, they can reference only 4 GB of memory, which is why a 32-bit JVM is limited to a 4 GB heap size. (The same restriction applies at the operating system level, which is why any 32-bit process is limited to 4GB of address space.) When oops are 64 bits long, they can reference terabytes of memory.
    What if there were 35-bit oops? Then the pointer could reference 32 GB of memory and still take up less space in the heap than 64-bit references. The problem is that there aren’t 35-bit registers in which to store such references. Instead, though, the JVM can assume that the last 3 bits of the reference are all 0. Now every reference can be stored in 32 bits in the heap. When the reference is stored into a 64-bit register, the JVM can shift it left by 3 bits (adding three zeros at the end). When the reference is saved from a register, the JVM can right-shift it by 3 bits, discarding the zeros at the end.
    This allows JVM to use pointers that can reference 32 GB of memory while using only 32 bits in the heap. However it also means that the JVM cannot access any object at an address that isn’t divisible by 8, since any address from a compressed oop ends with three zeros. The first possible oop is 0x1, which when shifted becomes 0x8. The next oop is 0x2, which when shifted becomes 0x10 (16). Objects must therefore be located on an 8-byte boundary. As we know objects are already aligned on an 8-byte boundary in the JVM (in both the 32- and 64-bit versions); this is the optimal alignment for most processors. So nothing is lost by using compressed oops.
    A program that uses a 31 GB heap and compressed oops will usually be faster than a program that uses a 33 GB heap. Although the 33 GB heap is larger, the extra space used by the pointers in that heap means that the larger heap will perform more frequent GC cycles and have worse performance.
    Compressed oops are enabled using the -XX:+UseCompressedOops flag; in Java 7 and later versions, they are enabled by default whenever the maximum heap size is less than 32 GB.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值