OpenJDK 19 和压缩指针

OpenJDK 19 and compressed pointers

提问人:Cornel Creanga 提问时间:11/6/2022 最后编辑:Mark RotteveelCornel Creanga 更新时间:11/26/2022 访问量:345

问:

我很难理解压缩指针在 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-quarks/23-compressed-references/

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

jvm 热点 java-19

评论

2赞 Eugene 11/8/2022
基本上是这个的复制品

答:

8赞 Holger 11/7/2022 #1

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

您看到的区别在于类指针的大小,该指针不指向堆内存中的位置。但由于历史原因,该选项与该选项的存在有关。因此,当堆大小不允许使用压缩对象指针时,压缩类指针会被禁用作为副作用。-XX:+UseCompressedClassPointers-XX:+UseCompressedOops

JDK-8241825,使压缩的 oops 和压缩的类指针独立解决此问题,并已在 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 个字节。

评论

2赞 Cornel Creanga 11/8/2022
谢谢你的解释。我还将添加一个链接,该链接将来可能对某人有用 stuefe.de/posts/metaspace/what-is-compressed-class-space