繁体   English   中英

OpenJDK 19 和压缩指针

[英]OpenJDK 19 and compressed pointers

我很难理解压缩指针在 Java 19 中的工作原理,感谢您的帮助。

在 Java 11 中,对于低于 32GiB(压缩指针)的堆,引用大小为 4,对于更大的堆,引用大小为 8。 在 Java 19 中,即使对于更大的堆,它们似乎也占用 4 个字节(如何?)。

细节:

Java 版本:OpenJDK Java 11.0.12 和 OpenJDK Java 19.0.1

命令行:

-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -Xlog:gc+heap+coops -Xms41g -Xmx41g -XX:+AlwaysPreTouch

-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -Xlog:gc+heap+coops -Xms31g -Xmx31g -XX:+AlwaysPreTouch

代码: https://github.com/cornelcreanga/fun/blob/master/src/main/java/com/ccreanga/various/RandomAllocate.java - 代码取自https://shipilev.net/jvm/anatomy -夸克/23-压缩参考/

使用 Java 11 和 19 运行这段代码,您可以看到 Java 19 中的 memory 大小小于 Java 11 中的堆 > 32 GiB。 对于较小的堆,大小几乎相同。

您正在查看byte[]数组的布局和java.lang.Object的实例。 它们都不包含对堆内 object 的引用。

您看到的差异在于class 指针的大小,它未指向堆 memory 内的某个位置。但是由于历史原因,选项-XX:+UseCompressedClassPointers绑定到-XX:+UseCompressedOops的存在选项。 因此,当堆大小不允许压缩 object 指针时,作为副作用,压缩的 class 指针将被禁用。

JDK-8241825,使压缩的 oops 和压缩的 class 指针独立解决这个问题,并已通过 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 或更新版本。

差异显然是由 class 指针和填充引起的,但是三个 object 引用在每个 JVM 版本中需要 24 个字节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM