根据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 比特。
对象默认以 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: 压缩引用