jvm OpenJdk 19和压缩指针

vbkedwbf  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(116)

我很难理解压缩指针在Java 19中是如何工作的,请帮助。
在java 11中,对于小于32 GB的堆,引用大小为4(压缩指针),对于更大的堆,引用大小为8。在Java 19中,即使对于更大的堆,引用大小也为4字节(如何??)。
详细信息:
Java版本:开放式数据库Java 11.0.12和开放式数据库Java 19.0.1
命令行:
-XX:+解锁实验性虚拟机选项-XX:+使用EpsilonGC-Xlog:gc -Xlog:gc+堆+coops -Xms 41 g-Xmx 41 g-XX:+始终预接触
-XX:+解锁实验性虚拟机选项-XX:+使用EpsilonGC-Xlog:gc -Xlog:gc+堆+coops -Xms 31 g-Xmx 31 g-XX:+始终预接触
代码:https://github.com/cornelcreanga/fun/blob/master/src/main/java/com/ccreanga/various/RandomAllocate.java-代码取自https://shipilev.net/jvm/anatomy-quarks/23-compressed-references/
在Java 11/19中运行这段代码,可以看到,对于大于32 GB的堆,Java 19中的内存大小比Java 11中的小。对于较小的堆,大小几乎相同。

  • 谢谢-谢谢
up9lanfz

up9lanfz1#

您正在查看byte[]数组和java.lang.Object示例的布局。它们都不包含对堆内对象的引用。
您所看到的差异在于 class pointer 的大小,它并不指向堆内存中的某个位置。但是由于历史原因,-XX:+UseCompressedClassPointers选项与-XX:+UseCompressedOops选项绑定在一起。因此,当堆大小不允许压缩对象指针时,压缩类指针也会被禁用。
JDK-8241825, Make compressed oops and compressed class pointers independent解决了这个问题,JDK 15已经解决了这个问题。
所以当我把你的程序改成

System.out.println(ClassLayout.parseInstance(new Object[3]).toPrintable());

然后用41GB的堆运行它,我得到

[Ljava.lang.Object; object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8                    (object header: class)    0x000001f54bec41e0
 16   4                    (array length)            3
 20   4                    (alignment/padding gap)
 24  24   java.lang.Object Object;.<elements>        N/A
Instance size: 48 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total

JDK 15之前的版本和

[Ljava.lang.Object; object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   4                    (object header: class)    0x000020fc
 12   4                    (array length)            3
 16  24   java.lang.Object Object;.<elements>        N/A
Instance size: 40 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

JDK 15或更高版本。
这种差异显然是由类指针和填充引起的,但是在每个JVM版本中,三个对象引用需要24个字节。

相关问题