OpenJDK 19 和压缩指针

Cor*_*nga 8 java jvm jvm-hotspot java-19

我很难理解压缩指针在 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 运行此代码,您可以看到,对于 > 32 GiB 的堆,Java 19 中的内存大小低于 Java 11 中的内存大小。对于较小的堆,大小几乎相同。

Hol*_*ger 8

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

\n

您看到的差异在于类指针的大小,它没有指向堆内存内的位置。但由于历史原因,该选项-XX:+UseCompressedClassPointers必须存在-XX:+UseCompressedOops。因此,当堆大小不允许压缩对象指针时,压缩类指针就会被禁用,这是一个副作用。

\n

JDK-8241825,使压缩的oops和压缩的类指针独立了这个问题,并已通过 JDK\xc2\xa015 解决。

\n

所以当我将你的程序更改为

\n
System.out.println(ClassLayout.parseInstance(new Object[3]).toPrintable());\n
Run Code Online (Sandbox Code Playgroud)\n

并使用 41GB 堆运行它,我得到

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

早于 JDK\xc2\xa015 和

\n
[Ljava.lang.Object; object internals:\nOFF  SZ               TYPE DESCRIPTION               VALUE\n  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)\n  8   4                    (object header: class)    0x000020fc\n 12   4                    (array length)            3\n 16  24   java.lang.Object Object;.<elements>        N/A\nInstance size: 40 bytes\nSpace losses: 0 bytes internal + 0 bytes external = 0 bytes total\n
Run Code Online (Sandbox Code Playgroud)\n

使用 JDK\xc2\xa015 或更高版本。

\n

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

\n

  • 感谢您的解释。我还将添加一个可能对将来的人有用的链接 https://stuefe.de/posts/metaspace/what-is-compressed-class-space/ (2认同)