所以,我试图运行一些简单的代码,jdk-8,通过 jol 输出
System.out.println(VMSupport.vmDetails());
Integer i = new Integer(23);
System.out.println(ClassLayout.parseInstance(i)
.toPrintable());
第一次尝试是在禁用压缩 oops 和压缩 klass 的情况下在 64 位 JVM 上运行它。
-XX:-UseCompressedOops -XX:-UseCompressedClassPointers
几乎预期的输出是:
Running 64-bit HotSpot VM.
Objects are 8 bytes aligned.
java.lang.Integer object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 48 33 36 97 (01001000 00110011 00110110 10010111) (-1758055608)
12 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
16 4 int Integer.value 23
20 4 (loss due to the next object alignment)
Instance size: 24 bytes (reported by Instrumentation API)
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
这是有道理的:8 字节 klass 字 + 8 字节标记字 + 4 字节实际值和 4 字节填充(与 8 字节对齐)= 24 字节。
第二次尝试在 64 位 JVM 上使用启用了压缩 oops 的压缩 klass 来运行它。
同样,输出是很容易理解的:
Running 64-bit HotSpot VM.
Using compressed oop with 3-bit shift.
Using compressed klass with 3-bit shift.
Objects are 8 bytes aligned.
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) f9 33 01 f8 (11111001 00110011 00000001 11111000) (-134138887)
12 4 int Dummy.i 42
Instance size: 16 bytes (reported by Instrumentation API).
4 字节压缩 oop(klass 字)+ 8 字节标记字 + 4 字节值 + 无空间损失 = 16 字节。
对我来说没有意义的是这个用例:
-XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:ObjectAlignmentInBytes=16
输出是这样的:
Running 64-bit HotSpot VM.
Using compressed oop with 4-bit shift.
Using compressed klass with 0x0000001000000000 base address and 0-bit shift.
我真的很期待两者都是“4 位移位”。为什么他们不是?
EDIT第二个示例的运行方式为:
XX:+UseCompressedOops -XX:+UseCompressedClassPointers
第三个是:
-XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:ObjectAlignmentInBytes=16