JVM测试指针压缩

根据es官方文档的说明,在启动参数中加上 -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode (在jvm.options).通过es启动指定内存大小测试

28G
heap address: 0x00000000c0000000, size: 28672 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
30G
heap address: 0x0000000080000000, size: 30720 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
31G
Protected page at the reserved heap base: 0x00007f3277e00000 / 2097152 bytes
32G
null nothing output

通过网友的文章中找到这种方式来测试

java -server -Xms30G -Xmx30G -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version
--------------------------------------------------30G
heap address: 0x0000000080000000, size: 30720 MB, Compressed Oops mode: Zero based, Oop shift amount: 3

Narrow klass base: 0x0000000800000000, Narrow klass shift: 0
Compressed class space size: 1073741824 Address: 0x0000000800000000 Req Addr: 0x0000000800000000
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
--------------------------------------------------31G
Protected page at the reserved heap base: 0x00007fd4e0e00000 / 2097152 bytes

heap address: 0x00007fd4e1000000, size: 31744 MB, Compressed Oops mode: Non-zero based:0x00007fd4e0fff000, Oop shift amount: 3

Narrow klass base: 0x00007fd3f6000000, Narrow klass shift: 0
Compressed class space size: 1073741824 Address: 0x00007fd3f6000000 Req Addr: 0x00007fdca1000000
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

“基于零”的模式
但是如果我们无法将未处理的引用放入 32 比特,那么该怎么办?还有一个办法,利用对象对齐这一事实:对象的起始位置总是以对齐的倍数。所以未处理引用的低位总是零。这为存储大于 32 比特的有效位提供了途径。最简单的方式是引用比特右移,这使得我们可以将 2(32+shift) 字节堆内存编码为 32 比特。

画图描述,大致是这样:ddd

对象默认以 8 字节对齐,移动3位(23 = 8),因此我们可以表示 235 = 32 GB 堆内存。由于堆内存的起始位置也不是从零开始,所以实际的可以编码的地址空间会小一些。

在 Hotspot 中,这种模式称为“基于零的压缩普通对象指针”,例如:

java -server -Xms30G -Xmx30G -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version
heap address: 0x0000000080000000, size: 30720 MB, Compressed Oops mode: Zero based, Oop shift amount: 3

“基于非零”的模式
但是基于零的压缩引用仍然依赖堆内存映射在较低地址的假设。如果不是,我们可以使用非零的堆内存起始地址来解码。这基本与基于零的模式一样,但是现在堆内存的起始地址非零,并且参与实际的编码和解码。

在 Hotspot 中,这种模式称为“基于非零”的模式,你可以从这样的日志中看到

java -server -Xms31G -Xmx31G -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version
heap address: 0x00007fd4e1000000, size: 31744 MB, Compressed Oops mode: Non-zero based:0x00007fd4e0fff000, Oop shift amount: 3

画图描述,大致是这样:

参考资料:【译】JVM Anatomy Quark #23: 压缩引用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值